@phenx-inc/ctlsurf 0.3.5 → 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 -49
- package/out/headless/index.mjs.map +2 -2
- package/out/main/index.js +67 -49
- package/package.json +1 -1
- package/src/main/timeTracker.ts +74 -45
- package/src/main/workerWs.ts +0 -6
package/out/headless/index.mjs
CHANGED
|
@@ -6056,12 +6056,6 @@ var WorkerWsClient = class {
|
|
|
6056
6056
|
this.send({ type: "terminal_resize", cols, rows });
|
|
6057
6057
|
}
|
|
6058
6058
|
sendChatLog(entry) {
|
|
6059
|
-
log("[worker-ws] chat_log DEBUG", {
|
|
6060
|
-
type: entry.type,
|
|
6061
|
-
chars: entry.content.length,
|
|
6062
|
-
lines: entry.content.split("\n").length,
|
|
6063
|
-
preview: entry.content.slice(0, 500)
|
|
6064
|
-
});
|
|
6065
6059
|
this.send({ type: "chat_log", entry });
|
|
6066
6060
|
}
|
|
6067
6061
|
doConnect() {
|
|
@@ -6277,55 +6271,68 @@ var TimeTracker = class {
|
|
|
6277
6271
|
if (this.sessions.has(tabId)) {
|
|
6278
6272
|
await this.endSession(tabId);
|
|
6279
6273
|
}
|
|
6280
|
-
|
|
6281
|
-
|
|
6282
|
-
|
|
6283
|
-
|
|
6284
|
-
|
|
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);
|
|
6285
6299
|
}
|
|
6286
|
-
|
|
6287
|
-
|
|
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;
|
|
6288
6315
|
const row = await this.api.addRow(blockId, {
|
|
6289
|
-
Started: formatStarted(startedAt),
|
|
6290
|
-
"Active Time":
|
|
6291
|
-
"Last Updated": new Date(
|
|
6292
|
-
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,
|
|
6293
6320
|
Worker: os2.hostname(),
|
|
6294
|
-
Session: sessionUuid,
|
|
6321
|
+
Session: s.sessionUuid,
|
|
6295
6322
|
Notes: ""
|
|
6296
6323
|
});
|
|
6297
6324
|
const rowId = row?.id;
|
|
6298
6325
|
if (!rowId) {
|
|
6299
|
-
log2(
|
|
6300
|
-
return;
|
|
6326
|
+
log2(`addRow returned no id for tab=${tabId}; will retry on next checkpoint`);
|
|
6327
|
+
return false;
|
|
6301
6328
|
}
|
|
6302
|
-
|
|
6303
|
-
|
|
6304
|
-
|
|
6305
|
-
|
|
6306
|
-
agentName,
|
|
6307
|
-
idleTimeoutMin,
|
|
6308
|
-
startedAt,
|
|
6309
|
-
lastActivity: startedAt,
|
|
6310
|
-
activeMs: 0,
|
|
6311
|
-
idleTimeoutMs: Math.max(1, idleTimeoutMin) * 60 * 1e3,
|
|
6312
|
-
firstCheckpointTimer: null,
|
|
6313
|
-
checkpointTimer: null,
|
|
6314
|
-
ended: false
|
|
6315
|
-
};
|
|
6316
|
-
state.firstCheckpointTimer = setTimeout(() => {
|
|
6317
|
-
void this.checkpoint(tabId);
|
|
6318
|
-
const live = this.sessions.get(tabId);
|
|
6319
|
-
if (live && !live.ended) {
|
|
6320
|
-
live.checkpointTimer = setInterval(() => {
|
|
6321
|
-
void this.checkpoint(tabId);
|
|
6322
|
-
}, CHECKPOINT_INTERVAL_MS);
|
|
6323
|
-
}
|
|
6324
|
-
}, FIRST_CHECKPOINT_DELAY_MS);
|
|
6325
|
-
this.sessions.set(tabId, state);
|
|
6326
|
-
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;
|
|
6327
6333
|
} catch (err) {
|
|
6328
|
-
log2(`
|
|
6334
|
+
log2(`tryResolve failed for tab=${tabId}: ${err?.message || err}`);
|
|
6335
|
+
return false;
|
|
6329
6336
|
}
|
|
6330
6337
|
}
|
|
6331
6338
|
isTracking(tabId) {
|
|
@@ -6365,14 +6372,21 @@ var TimeTracker = class {
|
|
|
6365
6372
|
async endSession(tabId) {
|
|
6366
6373
|
const s = this.sessions.get(tabId);
|
|
6367
6374
|
if (!s || s.ended) return;
|
|
6368
|
-
s.ended = true;
|
|
6369
6375
|
if (s.firstCheckpointTimer) clearTimeout(s.firstCheckpointTimer);
|
|
6370
6376
|
if (s.checkpointTimer) clearInterval(s.checkpointTimer);
|
|
6371
6377
|
try {
|
|
6372
|
-
|
|
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
|
+
}
|
|
6373
6386
|
} catch (err) {
|
|
6374
6387
|
log2(`endSession write failed: ${err?.message || err}`);
|
|
6375
6388
|
}
|
|
6389
|
+
s.ended = true;
|
|
6376
6390
|
this.sessions.delete(tabId);
|
|
6377
6391
|
}
|
|
6378
6392
|
async endAll() {
|
|
@@ -6382,13 +6396,16 @@ var TimeTracker = class {
|
|
|
6382
6396
|
async checkpoint(tabId) {
|
|
6383
6397
|
const s = this.sessions.get(tabId);
|
|
6384
6398
|
if (!s || s.ended) return;
|
|
6399
|
+
if (!s.blockId || !s.rowId) {
|
|
6400
|
+
if (!await this.tryResolve(tabId)) return;
|
|
6401
|
+
}
|
|
6385
6402
|
try {
|
|
6386
6403
|
await this.writeRow(s, Date.now());
|
|
6387
6404
|
} catch (err) {
|
|
6388
6405
|
log2(`checkpoint failed: ${err?.message || err}; retrying in 2s`);
|
|
6389
6406
|
setTimeout(() => {
|
|
6390
6407
|
const live = this.sessions.get(tabId);
|
|
6391
|
-
if (!live || live.ended) return;
|
|
6408
|
+
if (!live || live.ended || !live.blockId || !live.rowId) return;
|
|
6392
6409
|
this.writeRow(live, Date.now()).catch((err2) => {
|
|
6393
6410
|
log2(`checkpoint retry failed: ${err2?.message || err2}`);
|
|
6394
6411
|
});
|
|
@@ -6396,6 +6413,7 @@ var TimeTracker = class {
|
|
|
6396
6413
|
}
|
|
6397
6414
|
}
|
|
6398
6415
|
async writeRow(s, _endTimeMs) {
|
|
6416
|
+
if (!s.blockId || !s.rowId) return;
|
|
6399
6417
|
const activeMin = Math.round(s.activeMs / 6e4);
|
|
6400
6418
|
await this.api.updateRow(s.blockId, s.rowId, {
|
|
6401
6419
|
"Active Time": activeMin,
|