workday-daemon 0.18.0 → 0.19.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.
@@ -1,162 +1,21 @@
1
- import { readFileSync, writeFileSync, existsSync } from 'node:fs';
2
- import { join } from 'node:path';
3
- import { getDataDir } from '../core/config.js';
1
+ import { readFileSync } from 'node:fs';
4
2
  import { readDailyLog, writeDailyLog } from '../core/daily-log.js';
5
- import { PUSH_LOG_FILE, TEMPO_TOLERANCE_SECONDS } from '../core/constants.js';
6
3
  import { DayStatus } from '../core/types.js';
7
4
  import { buildReport } from './report-builder.js';
8
5
  import { getAccountId, resolveIssueIds } from './jira-client.js';
9
6
  import { TempoClient } from './tempo-client.js';
10
7
  import { invalidateApprovalCache } from './tempo-approvals.js';
11
- // ─── Push log persistence ────────────────────────────────────────────────
12
- function getPushLogPath() {
13
- return join(getDataDir(), PUSH_LOG_FILE);
14
- }
15
- function loadPushLog() {
16
- const path = getPushLogPath();
17
- if (!existsSync(path))
18
- return {};
19
- try {
20
- return JSON.parse(readFileSync(path, 'utf-8'));
21
- }
22
- catch {
23
- return {};
24
- }
25
- }
26
- function savePushLog(log) {
27
- writeFileSync(getPushLogPath(), JSON.stringify(log, null, 2), 'utf-8');
28
- }
29
- function pushLogKey(date, task, entryId) {
30
- return entryId ? `${date}|${task}|m:${entryId}` : `${date}|${task}`;
31
- }
8
+ import { loadPushLog, savePushLog, pushLogKey, loadTombstones, removeTombstonesByWorklogIds } from './push-log.js';
9
+ import { refreshSnapshotsInRange } from './tempo-snapshot.js';
10
+ import { buildPushPlan, formatHours } from './reconcile.js';
32
11
  // ─── Push plan ───────────────────────────────────────────────────────────
33
- /** Build a plan by comparing report entries with push log and existing Tempo worklogs */
34
- export function buildPushPlan(report, jiraMap, pushLog, tempoWorklogs) {
35
- const plan = [];
36
- // Index Tempo worklogs by (date, issueId) for fast lookup
37
- const tempoByKey = new Map();
38
- for (const wl of tempoWorklogs) {
39
- const key = `${wl.startDate}|${wl.issueId}`;
40
- const list = tempoByKey.get(key) ?? [];
41
- list.push(wl);
42
- tempoByKey.set(key, list);
43
- }
44
- // Worklogs we own as MANUAL entries — excluded from the session aggregate so a
45
- // session line never treats its own task's manual worklogs as extra/foreign.
46
- const manualOwnedTempoIds = new Set();
47
- for (const [key, logEntry] of Object.entries(pushLog)) {
48
- if (key.includes('|m:'))
49
- manualOwnedTempoIds.add(logEntry.tempoWorklogId);
50
- }
51
- // Track which Tempo worklogs are accounted for by our report
52
- const accountedTempoIds = new Set();
53
- for (const entry of report) {
54
- const jira = jiraMap.get(entry.task);
55
- if (!jira) {
56
- plan.push({
57
- date: entry.date, task: entry.task, targetSeconds: entry.totalSeconds,
58
- action: 'error', detail: 'Unresolved in Jira',
59
- kind: entry.kind, entryId: entry.entryId, description: entry.description, activity: entry.activity,
60
- });
61
- continue;
62
- }
63
- const tempoMatches = tempoByKey.get(`${entry.date}|${jira.issueId}`) ?? [];
64
- // ── Manual entry: its own worklog, keyed by entryId (stable across edits) ──
65
- if (entry.kind === 'manual') {
66
- const base = {
67
- date: entry.date, task: entry.task, targetSeconds: entry.totalSeconds,
68
- issueId: jira.issueId, kind: 'manual',
69
- entryId: entry.entryId, description: entry.description, activity: entry.activity,
70
- };
71
- const key = pushLogKey(entry.date, entry.task, entry.entryId);
72
- const logEntry = pushLog[key];
73
- const live = logEntry && tempoMatches.some(w => w.tempoWorklogId === logEntry.tempoWorklogId)
74
- ? logEntry : null;
75
- if (live) {
76
- accountedTempoIds.add(live.tempoWorklogId);
77
- const timeDrift = Math.abs(live.timeSpentSeconds - entry.totalSeconds) > TEMPO_TOLERANCE_SECONDS;
78
- const textDrift = (live.description ?? '') !== (entry.description ?? '')
79
- || (live.activity ?? '') !== (entry.activity ?? '');
80
- if (!timeDrift && !textDrift) {
81
- plan.push({ ...base, action: 'skip', detail: `Already pushed (${formatHours(live.timeSpentSeconds)})`, existingWorklogId: live.tempoWorklogId });
82
- }
83
- else {
84
- const detail = timeDrift
85
- ? `${formatHours(live.timeSpentSeconds)} → ${formatHours(entry.totalSeconds)}`
86
- : 'text/activity changed';
87
- plan.push({ ...base, action: 'update', detail, existingWorklogId: live.tempoWorklogId });
88
- }
89
- }
90
- else {
91
- // No live worklog of ours — create. Foreign worklogs on the same issue+date
92
- // are irrelevant: this entry has its own identity (entryId).
93
- plan.push({ ...base, action: 'create', detail: `New (${formatHours(entry.totalSeconds)})` });
94
- }
95
- continue;
96
- }
97
- // ── Session aggregate: one worklog per (date, task) ──
98
- const base = {
99
- date: entry.date, task: entry.task, targetSeconds: entry.totalSeconds,
100
- issueId: jira.issueId, kind: 'session',
101
- };
102
- const logEntry = pushLog[pushLogKey(entry.date, entry.task)];
103
- // Drop manual-owned worklogs: they belong to manual lines, not this aggregate.
104
- const sessionMatches = tempoMatches.filter(w => !manualOwnedTempoIds.has(w.tempoWorklogId));
105
- const validLogEntry = logEntry && sessionMatches.some(w => w.tempoWorklogId === logEntry.tempoWorklogId)
106
- ? logEntry : null;
107
- if (validLogEntry) {
108
- accountedTempoIds.add(validLogEntry.tempoWorklogId);
109
- const diff = Math.abs(validLogEntry.timeSpentSeconds - entry.totalSeconds);
110
- if (diff <= TEMPO_TOLERANCE_SECONDS) {
111
- plan.push({ ...base, action: 'skip', detail: `Already pushed (${formatHours(validLogEntry.timeSpentSeconds)})`, existingWorklogId: validLogEntry.tempoWorklogId });
112
- }
113
- else {
114
- plan.push({ ...base, action: 'update', detail: `${formatHours(validLogEntry.timeSpentSeconds)} → ${formatHours(entry.totalSeconds)}`, existingWorklogId: validLogEntry.tempoWorklogId });
115
- }
116
- for (const wl of sessionMatches)
117
- accountedTempoIds.add(wl.tempoWorklogId);
118
- }
119
- else if (sessionMatches.length > 0) {
120
- for (const wl of sessionMatches)
121
- accountedTempoIds.add(wl.tempoWorklogId);
122
- const existingTotal = sessionMatches.reduce((s, w) => s + w.timeSpentSeconds, 0);
123
- const diff = Math.abs(existingTotal - entry.totalSeconds);
124
- if (diff <= TEMPO_TOLERANCE_SECONDS) {
125
- plan.push({ ...base, action: 'skip', detail: `Exists in Tempo (${formatHours(existingTotal)})`, extraWorklogIds: sessionMatches.map(w => w.tempoWorklogId) });
126
- }
127
- else {
128
- plan.push({ ...base, action: 'create', detail: `Tempo has ${formatHours(existingTotal)}, adding ${formatHours(entry.totalSeconds)}`, extraWorklogIds: sessionMatches.map(w => w.tempoWorklogId) });
129
- }
130
- }
131
- else {
132
- plan.push({ ...base, action: 'create', detail: `New (${formatHours(entry.totalSeconds)})` });
133
- }
134
- }
135
- // Tempo-only worklogs (not matched by our report) — show, never mutate.
136
- for (const wl of tempoWorklogs) {
137
- if (accountedTempoIds.has(wl.tempoWorklogId))
138
- continue;
139
- let taskKey = `issue:${wl.issueId}`;
140
- for (const [key, jira] of jiraMap) {
141
- if (jira.issueId === wl.issueId) {
142
- taskKey = key;
143
- break;
144
- }
145
- }
146
- plan.push({
147
- date: wl.startDate, task: taskKey, targetSeconds: wl.timeSpentSeconds,
148
- action: 'skip', detail: `Tempo only (${formatHours(wl.timeSpentSeconds)})`,
149
- existingWorklogId: wl.tempoWorklogId, kind: 'session',
150
- });
151
- }
152
- // Sort by date, then task
153
- plan.sort((a, b) => a.date.localeCompare(b.date) || a.task.localeCompare(b.task));
154
- return plan;
155
- }
12
+ // The diff engine lives in reconcile.ts; re-exported here for existing callers.
13
+ export { buildPushPlan };
156
14
  // ─── Execute plan ────────────────────────────────────────────────────────
157
15
  /** Execute mutations from the plan, update push log */
158
16
  export async function executePlan(plan, tempoClient, accountId) {
159
17
  const pushLog = loadPushLog();
18
+ const deletedWorklogIds = new Set();
160
19
  let posted = 0;
161
20
  let updated = 0;
162
21
  let deleted = 0;
@@ -228,15 +87,49 @@ export async function executePlan(plan, tempoClient, accountId) {
228
87
  }
229
88
  break;
230
89
  }
90
+ case 'delete': {
91
+ if (!entry.existingWorklogId) {
92
+ failed++;
93
+ break;
94
+ }
95
+ try {
96
+ await tempoClient.deleteWorklog(entry.existingWorklogId);
97
+ delete pushLog[key]; // stray ownership, if any
98
+ deletedWorklogIds.add(entry.existingWorklogId);
99
+ deleted++;
100
+ console.log(` DEL ${entry.date} ${entry.task} ${formatHours(entry.targetSeconds)}`);
101
+ }
102
+ catch (err) {
103
+ failed++;
104
+ console.error(` FAIL DEL ${entry.date} ${entry.task}: ${err instanceof Error ? err.message : String(err)}`);
105
+ }
106
+ break;
107
+ }
231
108
  case 'error':
232
109
  failed++;
233
110
  break;
234
111
  }
235
112
  }
236
113
  savePushLog(pushLog);
114
+ if (deletedWorklogIds.size > 0) {
115
+ removeTombstonesByWorklogIds(deletedWorklogIds);
116
+ }
237
117
  return { posted, updated, deleted, skipped, failed };
238
118
  }
239
119
  // ─── Mark daily logs as pushed ───────────────────────────────────────────
120
+ /** Dates in [from, to] whose local day file exists — the stray-delete guard. */
121
+ function collectDatesWithData(from, to) {
122
+ const dates = new Set();
123
+ const current = new Date(from + 'T12:00:00Z');
124
+ const end = new Date(to + 'T12:00:00Z');
125
+ while (current <= end) {
126
+ const date = current.toISOString().slice(0, 10);
127
+ if (readDailyLog(date))
128
+ dates.add(date);
129
+ current.setUTCDate(current.getUTCDate() + 1);
130
+ }
131
+ return dates;
132
+ }
240
133
  function markDaysPushed(from, to) {
241
134
  const current = new Date(from + 'T12:00:00Z');
242
135
  const end = new Date(to + 'T12:00:00Z');
@@ -256,7 +149,7 @@ function markDaysPushed(from, to) {
256
149
  }
257
150
  /** Full push pipeline: build report → resolve Jira → fetch Tempo → plan → execute */
258
151
  export async function runPush(options) {
259
- const { from, to, commit, config, secrets, filePath } = options;
152
+ const { from, to, commit, config, secrets, filePath, force } = options;
260
153
  // Step 1: Build or load report
261
154
  let report;
262
155
  if (filePath) {
@@ -269,7 +162,15 @@ export async function runPush(options) {
269
162
  report = buildReport(from, to, config);
270
163
  console.log(`Built report: ${report.length} entries (${from} → ${to})`);
271
164
  }
272
- if (report.length === 0) {
165
+ // Local deletions may still need Tempo-side propagation even when the
166
+ // report is empty (a fully cleared pushed day, tombstoned entries).
167
+ const pushLog = loadPushLog();
168
+ const rangeTombstones = loadTombstones().filter(t => t.date >= from && t.date <= to);
169
+ const hasRangeOwnership = Object.keys(pushLog).some(k => {
170
+ const date = k.slice(0, 10);
171
+ return date >= from && date <= to;
172
+ });
173
+ if (report.length === 0 && rangeTombstones.length === 0 && !hasRangeOwnership) {
273
174
  return { dryRun: !commit, plan: [], result: { posted: 0, updated: 0, deleted: 0, skipped: 0, failed: 0 } };
274
175
  }
275
176
  // Step 2: Resolve Jira issue IDs
@@ -289,23 +190,51 @@ export async function runPush(options) {
289
190
  console.log(`Fetching Tempo worklogs (${from} → ${to})...`);
290
191
  const tempoWorklogs = await tempoClient.getUserWorklogs(accountId, from, to);
291
192
  console.log(`Found ${tempoWorklogs.length} existing worklog(s)`);
292
- // Step 4: Build plan
293
- const pushLog = loadPushLog();
294
- const plan = buildPushPlan(report, jiraMap, pushLog, tempoWorklogs);
193
+ // Step 4: Build plan. Tombstones whose worklog is already gone from Tempo
194
+ // (deleted remotely too) have nothing left to do — purge them silently.
195
+ const aliveIds = new Set(tempoWorklogs.map(w => w.tempoWorklogId));
196
+ const deadTombstones = rangeTombstones.filter(t => !aliveIds.has(t.tempoWorklogId));
197
+ if (deadTombstones.length > 0) {
198
+ removeTombstonesByWorklogIds(new Set(deadTombstones.map(t => t.tempoWorklogId)));
199
+ }
200
+ const plan = buildPushPlan(report, jiraMap, pushLog, tempoWorklogs, {
201
+ tombstones: rangeTombstones.filter(t => aliveIds.has(t.tempoWorklogId)),
202
+ from,
203
+ to,
204
+ datesWithData: collectDatesWithData(from, to),
205
+ });
295
206
  if (!commit) {
296
207
  return { dryRun: true, plan };
297
208
  }
209
+ // Conflict gate: "local wins" is a choice, not a default. A commit push
210
+ // that would overwrite Tempo-side edits stops here until the caller
211
+ // explicitly forces it — nothing (conflicted or not) is executed.
212
+ if (!force) {
213
+ const conflicted = plan.filter(e => e.conflict);
214
+ if (conflicted.length > 0) {
215
+ console.log(`Push blocked: ${conflicted.length} worklog(s) edited in Tempo since our push.`);
216
+ return { dryRun: false, plan, blockedByConflicts: true };
217
+ }
218
+ }
298
219
  // Step 5: Execute
299
- const actionable = plan.filter(e => e.action === 'create' || e.action === 'update');
220
+ const actionable = plan.filter(e => e.action === 'create' || e.action === 'update' || e.action === 'delete');
300
221
  if (actionable.length === 0) {
301
222
  console.log('Nothing to push.');
223
+ // Parity with Tempo is still a successful sync — seal the days, or an
224
+ // edited-then-reverted day stays Outdated forever (no mutation ever
225
+ // triggers the seal below). Plan errors (unresolved Jira) block it.
226
+ if (!plan.some(e => e.action === 'error')) {
227
+ markDaysPushed(from, to);
228
+ }
302
229
  return { dryRun: false, plan, result: { posted: 0, updated: 0, deleted: 0, skipped: 0, failed: 0 } };
303
230
  }
304
231
  console.log(`Executing ${actionable.length} mutation(s)...`);
305
232
  const result = await executePlan(plan, tempoClient, accountId);
306
- // Tempo-side totals changed — the approval snapshot is stale now.
307
- if (result.posted > 0 || result.updated > 0) {
233
+ // Tempo-side state changed: approval cache is stale; worklog snapshots are
234
+ // refetched right away so month statuses turn diff-based after every push.
235
+ if (result.posted > 0 || result.updated > 0 || result.deleted > 0) {
308
236
  invalidateApprovalCache();
237
+ await refreshSnapshotsInRange(from, to, secrets, accountId);
309
238
  }
310
239
  // Seal the day only on a clean push. A failed mutation (network, Jira limit, etc.)
311
240
  // must NOT mark the day pushed, or it would silently drop out of future syncs.
@@ -317,12 +246,4 @@ export async function runPush(options) {
317
246
  }
318
247
  return { dryRun: false, plan, result };
319
248
  }
320
- // ─── Helpers ─────────────────────────────────────────────────────────────
321
- function formatHours(seconds) {
322
- const hours = seconds / 3600;
323
- const rounded1 = parseFloat(hours.toFixed(1));
324
- if (Math.abs(hours - rounded1) < 0.01)
325
- return `${hours.toFixed(1)}h`;
326
- return `${hours.toFixed(2)}h`;
327
- }
328
249
  //# sourceMappingURL=tempo-pusher.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tempo-pusher.js","sourceRoot":"","sources":["../../src/push/tempo-pusher.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tempo-pusher.js","sourceRoot":"","sources":["../../src/push/tempo-pusher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,SAAS,EAA4G,MAAM,kBAAkB,CAAC;AACvJ,OAAO,EAAE,WAAW,EAA6D,MAAM,qBAAqB,CAAC;AAC7G,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAC;AACnH,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE5D,4EAA4E;AAE5E,gFAAgF;AAChF,OAAO,EAAE,aAAa,EAAE,CAAC;AAEzB,4EAA4E;AAE5E,uDAAuD;AACvD,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAA8B,EAC9B,WAAwB,EACxB,SAAiB;IAEjB,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;IAC9B,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAU,CAAC;IAC5C,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAEpG,QAAQ,KAAK,CAAC,MAAM,EAAE,CAAC;YACrB,KAAK,MAAM;gBACT,OAAO,EAAE,CAAC;gBACV,MAAM;YAER,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;oBAAC,MAAM,EAAE,CAAC;oBAAC,MAAM;gBAAC,CAAC;gBACxC,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,aAAa,CAAC;wBAC7C,OAAO,EAAE,KAAK,CAAC,OAAO;wBACtB,eAAe,EAAE,SAAS;wBAC1B,gBAAgB,EAAE,KAAK,CAAC,aAAa;wBACrC,SAAS,EAAE,KAAK,CAAC,IAAI;wBACrB,WAAW,EAAE,KAAK,CAAC,WAAW;wBAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;qBACzB,CAAC,CAAC;oBACH,OAAO,CAAC,GAAG,CAAC,GAAG;wBACb,cAAc,EAAE,MAAM,CAAC,cAAc;wBACrC,gBAAgB,EAAE,KAAK,CAAC,aAAa;wBACrC,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;wBAClC,WAAW,EAAE,KAAK,CAAC,WAAW;wBAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;qBACzB,CAAC;oBACF,MAAM,EAAE,CAAC;oBACT,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,WAAW,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;gBACxF,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,EAAE,CAAC;oBACT,OAAO,CAAC,KAAK,CAAC,eAAe,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAChH,CAAC;gBACD,MAAM;YACR,CAAC;YAED,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE,CAAC;oBAAC,MAAM,EAAE,CAAC;oBAAC,MAAM;gBAAC,CAAC;gBACpE,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,aAAa,CAAC,KAAK,CAAC,iBAAiB,EAAE;wBACtE,OAAO,EAAE,KAAK,CAAC,OAAO;wBACtB,eAAe,EAAE,SAAS;wBAC1B,gBAAgB,EAAE,KAAK,CAAC,aAAa;wBACrC,SAAS,EAAE,KAAK,CAAC,IAAI;wBACrB,WAAW,EAAE,KAAK,CAAC,WAAW;wBAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;qBACzB,CAAC,CAAC;oBACH,OAAO,CAAC,GAAG,CAAC,GAAG;wBACb,cAAc,EAAE,MAAM,CAAC,cAAc;wBACrC,gBAAgB,EAAE,KAAK,CAAC,aAAa;wBACrC,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;wBAClC,WAAW,EAAE,KAAK,CAAC,WAAW;wBAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;qBACzB,CAAC;oBACF,OAAO,EAAE,CAAC;oBACV,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;gBACpE,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,EAAE,CAAC;oBACT,OAAO,CAAC,KAAK,CAAC,cAAc,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC/G,CAAC;gBACD,MAAM;YACR,CAAC;YAED,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE,CAAC;oBAAC,MAAM,EAAE,CAAC;oBAAC,MAAM;gBAAC,CAAC;gBAClD,IAAI,CAAC;oBACH,MAAM,WAAW,CAAC,aAAa,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;oBACzD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAuB,0BAA0B;oBACrE,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;oBAC/C,OAAO,EAAE,CAAC;oBACV,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,WAAW,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;gBACxF,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,EAAE,CAAC;oBACT,OAAO,CAAC,KAAK,CAAC,cAAc,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC/G,CAAC;gBACD,MAAM;YACR,CAAC;YAED,KAAK,OAAO;gBACV,MAAM,EAAE,CAAC;gBACT,MAAM;QACV,CAAC;IACH,CAAC;IAED,WAAW,CAAC,OAAO,CAAC,CAAC;IACrB,IAAI,iBAAiB,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QAC/B,4BAA4B,CAAC,iBAAiB,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AACvD,CAAC;AAED,4EAA4E;AAE5E,gFAAgF;AAChF,SAAS,oBAAoB,CAAC,IAAY,EAAE,EAAU;IACpD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,EAAE,GAAG,YAAY,CAAC,CAAC;IACxC,OAAO,OAAO,IAAI,GAAG,EAAE,CAAC;QACtB,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAChD,IAAI,YAAY,CAAC,IAAI,CAAC;YAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACxC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,EAAU;IAC9C,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,EAAE,GAAG,YAAY,CAAC,CAAC;IACxC,OAAO,OAAO,IAAI,GAAG,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;QACnC,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC7D,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACxD,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAE9B,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM,EAAE,CAAC;YAC3C,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;YAC9B,GAAG,CAAC,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACxC,aAAa,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;QACD,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC;AAgBD,qFAAqF;AACrF,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,OAAuB;IACnD,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAEvE,+BAA+B;IAC/B,IAAI,MAAuB,CAAC;IAC5B,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAiC,CAAC;QAC/D,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,UAAU,MAAM,CAAC,MAAM,iBAAiB,QAAQ,EAAE,CAAC,CAAC;IAClE,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,WAAW,CAAC,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,iBAAiB,MAAM,CAAC,MAAM,aAAa,IAAI,MAAM,EAAE,GAAG,CAAC,CAAC;IAC1E,CAAC;IAED,sEAAsE;IACtE,oEAAoE;IACpE,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;IAC9B,MAAM,eAAe,GAAG,cAAc,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IACrF,MAAM,iBAAiB,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;QACtD,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC5B,OAAO,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC9E,OAAO,EAAE,MAAM,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;IAC7G,CAAC;IAED,iCAAiC;IACjC,MAAM,WAAW,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,aAAa,WAAW,CAAC,MAAM,mBAAmB,CAAC,CAAC;IAChE,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAE5D,uDAAuD;IACvD,IAAI,SAAiB,CAAC;IACtB,IAAI,CAAC;QACH,SAAS,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,0CAA0C,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChH,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,YAAY,SAAS,EAAE,CAAC,CAAC;IAErC,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,4BAA4B,IAAI,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5D,MAAM,aAAa,GAAG,MAAM,WAAW,CAAC,eAAe,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;IAC7E,OAAO,CAAC,GAAG,CAAC,SAAS,aAAa,CAAC,MAAM,sBAAsB,CAAC,CAAC;IAEjE,0EAA0E;IAC1E,wEAAwE;IACxE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC;IACnE,MAAM,cAAc,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC;IACpF,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,4BAA4B,CAAC,IAAI,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IACnF,CAAC;IAED,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE;QAClE,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;QACvE,IAAI;QACJ,EAAE;QACF,aAAa,EAAE,oBAAoB,CAAC,IAAI,EAAE,EAAE,CAAC;KAC9C,CAAC,CAAC;IAEH,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAChC,CAAC;IAED,wEAAwE;IACxE,oEAAoE;IACpE,kEAAkE;IAClE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAChD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,iBAAiB,UAAU,CAAC,MAAM,6CAA6C,CAAC,CAAC;YAC7F,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,kBAAkB;IAClB,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC;IAC7G,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAChC,sEAAsE;QACtE,oEAAoE;QACpE,oEAAoE;QACpE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,EAAE,CAAC;YAC1C,cAAc,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC3B,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;IACvG,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,aAAa,UAAU,CAAC,MAAM,iBAAiB,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;IAE/D,2EAA2E;IAC3E,2EAA2E;IAC3E,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC;QAClE,uBAAuB,EAAE,CAAC;QAC1B,MAAM,uBAAuB,CAAC,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IAC9D,CAAC;IAED,mFAAmF;IACnF,+EAA+E;IAC/E,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,cAAc,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC3B,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,+BAA+B,MAAM,CAAC,MAAM,oCAAoC,CAAC,CAAC;IAChG,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AACzC,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { Secrets, TempoMonthSnapshot } from '../core/types.js';
2
+ export declare function getSnapshotPath(year: number, month: number): string;
3
+ /** Cached snapshot for a month, or null when absent/corrupted. */
4
+ export declare function loadMonthSnapshot(year: number, month: number): TempoMonthSnapshot | null;
5
+ export declare function saveMonthSnapshot(snapshot: TempoMonthSnapshot): void;
6
+ /** Fetch the month from Tempo and persist it as the current snapshot. */
7
+ export declare function fetchMonthSnapshot(year: number, month: number, secrets: Secrets, knownAccountId?: string): Promise<TempoMonthSnapshot>;
8
+ /**
9
+ * Drop cached snapshots for every month intersecting [from, to] — called
10
+ * after a push mutates Tempo, so the next sync refetches fresh state.
11
+ */
12
+ export declare function invalidateSnapshotsInRange(from: string, to: string): void;
13
+ /**
14
+ * Refetch snapshots for every month intersecting [from, to] — best effort:
15
+ * a month that fails to fetch gets its stale cache dropped instead, so it
16
+ * can never lie about the post-push state.
17
+ */
18
+ export declare function refreshSnapshotsInRange(from: string, to: string, secrets: Secrets, knownAccountId?: string): Promise<void>;
@@ -0,0 +1,98 @@
1
+ // Remote snapshot of the user's Tempo worklogs, one file per month
2
+ // (data/tempo-cache/YYYY-MM.json, atomic write). This is the remote side of
3
+ // mirror-sync: reconcile compares the desired report against this snapshot,
4
+ // not against push-log memory. No TTL — a snapshot stays valid until a push
5
+ // mutates Tempo (invalidated) or the caller forces a refresh.
6
+ import { readFileSync, writeFileSync, renameSync, existsSync, mkdirSync, unlinkSync } from 'node:fs';
7
+ import { join } from 'node:path';
8
+ import { getDataDir } from '../core/config.js';
9
+ import { TEMPO_CACHE_DIR, TMP_EXTENSION } from '../core/constants.js';
10
+ import { TempoClient } from './tempo-client.js';
11
+ import { getAccountId } from './jira-client.js';
12
+ import { getMonthRange } from './month-report.js';
13
+ function monthKey(year, month) {
14
+ return `${year}-${String(month).padStart(2, '0')}`;
15
+ }
16
+ export function getSnapshotPath(year, month) {
17
+ return join(getDataDir(), TEMPO_CACHE_DIR, `${monthKey(year, month)}.json`);
18
+ }
19
+ /** Cached snapshot for a month, or null when absent/corrupted. */
20
+ export function loadMonthSnapshot(year, month) {
21
+ const path = getSnapshotPath(year, month);
22
+ if (!existsSync(path))
23
+ return null;
24
+ try {
25
+ return JSON.parse(readFileSync(path, 'utf-8'));
26
+ }
27
+ catch {
28
+ return null;
29
+ }
30
+ }
31
+ export function saveMonthSnapshot(snapshot) {
32
+ const [year, month] = snapshot.month.split('-').map(Number);
33
+ const path = getSnapshotPath(year, month);
34
+ mkdirSync(join(getDataDir(), TEMPO_CACHE_DIR), { recursive: true });
35
+ const tmpPath = path + TMP_EXTENSION;
36
+ writeFileSync(tmpPath, JSON.stringify(snapshot, null, 2), 'utf-8');
37
+ renameSync(tmpPath, path);
38
+ }
39
+ /** Fetch the month from Tempo and persist it as the current snapshot. */
40
+ export async function fetchMonthSnapshot(year, month, secrets, knownAccountId) {
41
+ const accountId = knownAccountId ?? await getAccountId(secrets);
42
+ const client = new TempoClient(secrets.Tempo_Token);
43
+ const { from, to } = getMonthRange(year, month);
44
+ const worklogs = await client.getUserWorklogs(accountId, from, to);
45
+ const snapshot = {
46
+ month: monthKey(year, month),
47
+ accountId,
48
+ fetchedAt: new Date().toISOString(),
49
+ worklogs,
50
+ };
51
+ saveMonthSnapshot(snapshot);
52
+ return snapshot;
53
+ }
54
+ /**
55
+ * Drop cached snapshots for every month intersecting [from, to] — called
56
+ * after a push mutates Tempo, so the next sync refetches fresh state.
57
+ */
58
+ export function invalidateSnapshotsInRange(from, to) {
59
+ let [year, month] = from.slice(0, 7).split('-').map(Number);
60
+ const lastKey = to.slice(0, 7);
61
+ while (monthKey(year, month) <= lastKey) {
62
+ try {
63
+ unlinkSync(getSnapshotPath(year, month));
64
+ }
65
+ catch { /* absent is fine */ }
66
+ month++;
67
+ if (month > 12) {
68
+ month = 1;
69
+ year++;
70
+ }
71
+ }
72
+ }
73
+ /**
74
+ * Refetch snapshots for every month intersecting [from, to] — best effort:
75
+ * a month that fails to fetch gets its stale cache dropped instead, so it
76
+ * can never lie about the post-push state.
77
+ */
78
+ export async function refreshSnapshotsInRange(from, to, secrets, knownAccountId) {
79
+ let [year, month] = from.slice(0, 7).split('-').map(Number);
80
+ const lastKey = to.slice(0, 7);
81
+ while (monthKey(year, month) <= lastKey) {
82
+ try {
83
+ await fetchMonthSnapshot(year, month, secrets, knownAccountId);
84
+ }
85
+ catch {
86
+ try {
87
+ unlinkSync(getSnapshotPath(year, month));
88
+ }
89
+ catch { /* absent is fine */ }
90
+ }
91
+ month++;
92
+ if (month > 12) {
93
+ month = 1;
94
+ year++;
95
+ }
96
+ }
97
+ }
98
+ //# sourceMappingURL=tempo-snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tempo-snapshot.js","sourceRoot":"","sources":["../../src/push/tempo-snapshot.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "workday-daemon",
3
- "version": "0.18.0",
3
+ "version": "0.19.0",
4
4
  "description": "Lightweight activity tracker & timesheet tool",
5
5
  "type": "module",
6
6
  "bin": {
@@ -17,7 +17,7 @@
17
17
  "build": "tsc",
18
18
  "start": "node dist/daemon.js",
19
19
  "cli": "tsx src/cli.ts",
20
- "test": "tsx tests/unit/stamina-evidence.test.ts && tsx tests/unit/candidate-lifecycle.test.ts && tsx tests/unit/honest-session-end.test.ts && tsx tests/unit/gap-detection.test.ts && tsx tests/unit/janitor.test.ts && tsx tests/unit/stop-marker.test.ts && tsx tests/unit/report-clamp.test.ts && tsx tests/unit/update-manager.test.ts && tsx tests/unit/manual-entries.test.ts && tsx tests/unit/favorites.test.ts && tsx tests/unit/jira-search.test.ts && tsx tests/unit/day-start.test.ts && tsx tests/unit/push-plan.test.ts && tsx tests/unit/month-report.test.ts && tsx tests/unit/day-edit.test.ts && tsx tests/integration/evidence-rebase.test.ts && tsx tests/integration/commit-ledger.test.ts",
20
+ "test": "tsx tests/unit/stamina-evidence.test.ts && tsx tests/unit/candidate-lifecycle.test.ts && tsx tests/unit/honest-session-end.test.ts && tsx tests/unit/gap-detection.test.ts && tsx tests/unit/janitor.test.ts && tsx tests/unit/stop-marker.test.ts && tsx tests/unit/report-clamp.test.ts && tsx tests/unit/update-manager.test.ts && tsx tests/unit/manual-entries.test.ts && tsx tests/unit/favorites.test.ts && tsx tests/unit/jira-search.test.ts && tsx tests/unit/day-start.test.ts && tsx tests/unit/push-plan.test.ts && tsx tests/unit/push-log.test.ts && tsx tests/unit/tempo-client.test.ts && tsx tests/unit/tempo-snapshot.test.ts && tsx tests/unit/month-report.test.ts && tsx tests/unit/day-edit.test.ts && tsx tests/integration/evidence-rebase.test.ts && tsx tests/integration/commit-ledger.test.ts",
21
21
  "prepublishOnly": "npm run build"
22
22
  },
23
23
  "keywords": [