@phenx-inc/ctlsurf 0.3.6 → 0.3.7
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/out/headless/index.mjs +67 -43
- package/out/headless/index.mjs.map +2 -2
- package/out/main/index.js +67 -43
- package/package.json +1 -1
- package/src/main/timeTracker.ts +74 -45
package/out/headless/index.mjs
CHANGED
|
@@ -6271,55 +6271,68 @@ var TimeTracker = class {
|
|
|
6271
6271
|
if (this.sessions.has(tabId)) {
|
|
6272
6272
|
await this.endSession(tabId);
|
|
6273
6273
|
}
|
|
6274
|
-
|
|
6275
|
-
|
|
6276
|
-
|
|
6277
|
-
|
|
6278
|
-
|
|
6274
|
+
const startedAt = Date.now();
|
|
6275
|
+
const state = {
|
|
6276
|
+
blockId: null,
|
|
6277
|
+
rowId: null,
|
|
6278
|
+
sessionUuid: randomUUID(),
|
|
6279
|
+
cwd,
|
|
6280
|
+
agentName,
|
|
6281
|
+
idleTimeoutMin,
|
|
6282
|
+
startedAt,
|
|
6283
|
+
lastActivity: startedAt,
|
|
6284
|
+
activeMs: 0,
|
|
6285
|
+
idleTimeoutMs: Math.max(1, idleTimeoutMin) * 60 * 1e3,
|
|
6286
|
+
firstCheckpointTimer: null,
|
|
6287
|
+
checkpointTimer: null,
|
|
6288
|
+
ended: false
|
|
6289
|
+
};
|
|
6290
|
+
this.sessions.set(tabId, state);
|
|
6291
|
+
await this.tryResolve(tabId);
|
|
6292
|
+
state.firstCheckpointTimer = setTimeout(() => {
|
|
6293
|
+
void this.checkpoint(tabId);
|
|
6294
|
+
const live = this.sessions.get(tabId);
|
|
6295
|
+
if (live && !live.ended) {
|
|
6296
|
+
live.checkpointTimer = setInterval(() => {
|
|
6297
|
+
void this.checkpoint(tabId);
|
|
6298
|
+
}, CHECKPOINT_INTERVAL_MS);
|
|
6279
6299
|
}
|
|
6280
|
-
|
|
6281
|
-
|
|
6300
|
+
}, FIRST_CHECKPOINT_DELAY_MS);
|
|
6301
|
+
const pending = !state.blockId || !state.rowId;
|
|
6302
|
+
log2(`Started tracking tab=${tabId} agent="${agentName}" cwd=${cwd}${pending ? " (pending datastore \u2014 will retry on each checkpoint)" : ""}`);
|
|
6303
|
+
}
|
|
6304
|
+
/** Attempts to locate (or create) the datastore + add the session row.
|
|
6305
|
+
* Returns true once the session is resolved (blockId + rowId set).
|
|
6306
|
+
* Safe to call repeatedly: re-running while pending will keep retrying;
|
|
6307
|
+
* once resolved it's a no-op. */
|
|
6308
|
+
async tryResolve(tabId) {
|
|
6309
|
+
const s = this.sessions.get(tabId);
|
|
6310
|
+
if (!s) return false;
|
|
6311
|
+
if (s.blockId && s.rowId) return true;
|
|
6312
|
+
try {
|
|
6313
|
+
const blockId = await this.ensureDatastore(s.cwd);
|
|
6314
|
+
if (!blockId) return false;
|
|
6282
6315
|
const row = await this.api.addRow(blockId, {
|
|
6283
|
-
Started: formatStarted(startedAt),
|
|
6284
|
-
"Active Time":
|
|
6285
|
-
"Last Updated": new Date(
|
|
6286
|
-
Agent: agentName,
|
|
6316
|
+
Started: formatStarted(s.startedAt),
|
|
6317
|
+
"Active Time": Math.round(s.activeMs / 6e4),
|
|
6318
|
+
"Last Updated": (/* @__PURE__ */ new Date()).toISOString(),
|
|
6319
|
+
Agent: s.agentName,
|
|
6287
6320
|
Worker: os2.hostname(),
|
|
6288
|
-
Session: sessionUuid,
|
|
6321
|
+
Session: s.sessionUuid,
|
|
6289
6322
|
Notes: ""
|
|
6290
6323
|
});
|
|
6291
6324
|
const rowId = row?.id;
|
|
6292
6325
|
if (!rowId) {
|
|
6293
|
-
log2(
|
|
6294
|
-
return;
|
|
6326
|
+
log2(`addRow returned no id for tab=${tabId}; will retry on next checkpoint`);
|
|
6327
|
+
return false;
|
|
6295
6328
|
}
|
|
6296
|
-
|
|
6297
|
-
|
|
6298
|
-
|
|
6299
|
-
|
|
6300
|
-
agentName,
|
|
6301
|
-
idleTimeoutMin,
|
|
6302
|
-
startedAt,
|
|
6303
|
-
lastActivity: startedAt,
|
|
6304
|
-
activeMs: 0,
|
|
6305
|
-
idleTimeoutMs: Math.max(1, idleTimeoutMin) * 60 * 1e3,
|
|
6306
|
-
firstCheckpointTimer: null,
|
|
6307
|
-
checkpointTimer: null,
|
|
6308
|
-
ended: false
|
|
6309
|
-
};
|
|
6310
|
-
state.firstCheckpointTimer = setTimeout(() => {
|
|
6311
|
-
void this.checkpoint(tabId);
|
|
6312
|
-
const live = this.sessions.get(tabId);
|
|
6313
|
-
if (live && !live.ended) {
|
|
6314
|
-
live.checkpointTimer = setInterval(() => {
|
|
6315
|
-
void this.checkpoint(tabId);
|
|
6316
|
-
}, CHECKPOINT_INTERVAL_MS);
|
|
6317
|
-
}
|
|
6318
|
-
}, FIRST_CHECKPOINT_DELAY_MS);
|
|
6319
|
-
this.sessions.set(tabId, state);
|
|
6320
|
-
log2(`Started tracking tab=${tabId} agent="${agentName}" cwd=${cwd}`);
|
|
6329
|
+
s.blockId = blockId;
|
|
6330
|
+
s.rowId = rowId;
|
|
6331
|
+
log2(`Resolved datastore for tab=${tabId} (cwd=${s.cwd})`);
|
|
6332
|
+
return true;
|
|
6321
6333
|
} catch (err) {
|
|
6322
|
-
log2(`
|
|
6334
|
+
log2(`tryResolve failed for tab=${tabId}: ${err?.message || err}`);
|
|
6335
|
+
return false;
|
|
6323
6336
|
}
|
|
6324
6337
|
}
|
|
6325
6338
|
isTracking(tabId) {
|
|
@@ -6359,14 +6372,21 @@ var TimeTracker = class {
|
|
|
6359
6372
|
async endSession(tabId) {
|
|
6360
6373
|
const s = this.sessions.get(tabId);
|
|
6361
6374
|
if (!s || s.ended) return;
|
|
6362
|
-
s.ended = true;
|
|
6363
6375
|
if (s.firstCheckpointTimer) clearTimeout(s.firstCheckpointTimer);
|
|
6364
6376
|
if (s.checkpointTimer) clearInterval(s.checkpointTimer);
|
|
6365
6377
|
try {
|
|
6366
|
-
|
|
6378
|
+
if (!s.blockId || !s.rowId) {
|
|
6379
|
+
await this.tryResolve(tabId);
|
|
6380
|
+
}
|
|
6381
|
+
if (s.blockId && s.rowId) {
|
|
6382
|
+
await this.writeRow(s, Date.now());
|
|
6383
|
+
} else {
|
|
6384
|
+
log2(`endSession for tab=${tabId}: never resolved datastore; ${Math.round(s.activeMs / 6e4)}min not recorded`);
|
|
6385
|
+
}
|
|
6367
6386
|
} catch (err) {
|
|
6368
6387
|
log2(`endSession write failed: ${err?.message || err}`);
|
|
6369
6388
|
}
|
|
6389
|
+
s.ended = true;
|
|
6370
6390
|
this.sessions.delete(tabId);
|
|
6371
6391
|
}
|
|
6372
6392
|
async endAll() {
|
|
@@ -6376,13 +6396,16 @@ var TimeTracker = class {
|
|
|
6376
6396
|
async checkpoint(tabId) {
|
|
6377
6397
|
const s = this.sessions.get(tabId);
|
|
6378
6398
|
if (!s || s.ended) return;
|
|
6399
|
+
if (!s.blockId || !s.rowId) {
|
|
6400
|
+
if (!await this.tryResolve(tabId)) return;
|
|
6401
|
+
}
|
|
6379
6402
|
try {
|
|
6380
6403
|
await this.writeRow(s, Date.now());
|
|
6381
6404
|
} catch (err) {
|
|
6382
6405
|
log2(`checkpoint failed: ${err?.message || err}; retrying in 2s`);
|
|
6383
6406
|
setTimeout(() => {
|
|
6384
6407
|
const live = this.sessions.get(tabId);
|
|
6385
|
-
if (!live || live.ended) return;
|
|
6408
|
+
if (!live || live.ended || !live.blockId || !live.rowId) return;
|
|
6386
6409
|
this.writeRow(live, Date.now()).catch((err2) => {
|
|
6387
6410
|
log2(`checkpoint retry failed: ${err2?.message || err2}`);
|
|
6388
6411
|
});
|
|
@@ -6390,6 +6413,7 @@ var TimeTracker = class {
|
|
|
6390
6413
|
}
|
|
6391
6414
|
}
|
|
6392
6415
|
async writeRow(s, _endTimeMs) {
|
|
6416
|
+
if (!s.blockId || !s.rowId) return;
|
|
6393
6417
|
const activeMin = Math.round(s.activeMs / 6e4);
|
|
6394
6418
|
await this.api.updateRow(s.blockId, s.rowId, {
|
|
6395
6419
|
"Active Time": activeMin,
|