agent-lyceum 0.33.0 → 0.33.1
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/dist/status-watch.d.ts +11 -0
- package/dist/status-watch.js +34 -10
- package/package.json +1 -1
package/dist/status-watch.d.ts
CHANGED
|
@@ -13,8 +13,19 @@ export type WatchFrame = {
|
|
|
13
13
|
* A task that was running in the previous frame and has finished (completed or partial) since is included once more, so the reader sees
|
|
14
14
|
* it finish (and can toast) before it is dropped. `tracked` is that previous set; it is replaced by the ids running now.
|
|
15
15
|
*/
|
|
16
|
+
/**
|
|
17
|
+
* Reports of finished runs, kept so a sweep does not rebuild them (about 300 ms each). An entry is reused while the
|
|
18
|
+
* run's state.json is unchanged and it is younger than `FINISHED_TTL_MS`; the TTL picks up what lives outside that file
|
|
19
|
+
* (unread mail, memory advice).
|
|
20
|
+
*/
|
|
21
|
+
export type FinishedCache = Map<string, {
|
|
22
|
+
stamp: string;
|
|
23
|
+
at: number;
|
|
24
|
+
report: StatusReport;
|
|
25
|
+
}>;
|
|
16
26
|
export declare function buildWatchFrame(project: ResolvedProject, tracked: Set<string>, opts?: {
|
|
17
27
|
allTasks?: boolean;
|
|
28
|
+
cache?: FinishedCache;
|
|
18
29
|
}): WatchFrame;
|
|
19
30
|
export interface WatchDeps {
|
|
20
31
|
/** The project, loaded again each time so config edits and new runs show up. */
|
package/dist/status-watch.js
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { buildStatusReport, buildTaskListReport, currentRun, isFinishedRun } from "./status.js";
|
|
4
|
+
const FINISHED_TTL_MS = 5 * 60_000;
|
|
5
|
+
function stampOf(project, id) {
|
|
6
|
+
try {
|
|
7
|
+
const st = fs.statSync(path.join(project.paths.runs, id, "state.json"));
|
|
8
|
+
return `${st.mtimeMs}:${st.size}`;
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return "";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
9
14
|
export function buildWatchFrame(project, tracked, opts) {
|
|
10
15
|
const all = buildTaskListReport(project).runs;
|
|
11
16
|
const running = all.filter((r) => r.state === "running").map((r) => r.run_id);
|
|
@@ -13,9 +18,27 @@ export function buildWatchFrame(project, tracked, opts) {
|
|
|
13
18
|
const runs = {};
|
|
14
19
|
// The web page keeps every task. The terminal watch drops one after it has finished, once the finish has been seen.
|
|
15
20
|
const ids = opts?.allTasks ? all.map((r) => r.run_id) : [...open, ...tracked];
|
|
16
|
-
|
|
21
|
+
const finished = new Set(all.filter(isFinishedRun).map((r) => r.run_id));
|
|
22
|
+
const cache = opts?.cache;
|
|
23
|
+
const now = Date.now();
|
|
24
|
+
for (const id of new Set(ids)) {
|
|
25
|
+
const stamp = cache && finished.has(id) ? stampOf(project, id) : "";
|
|
26
|
+
const hit = stamp ? cache?.get(id) : undefined;
|
|
27
|
+
if (hit && hit.stamp === stamp && now - hit.at < FINISHED_TTL_MS) {
|
|
28
|
+
runs[id] = hit.report;
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
17
31
|
runs[id] = buildStatusReport(project, id);
|
|
18
|
-
|
|
32
|
+
if (stamp)
|
|
33
|
+
cache?.set(id, { stamp, at: now, report: runs[id] });
|
|
34
|
+
}
|
|
35
|
+
if (cache)
|
|
36
|
+
for (const id of cache.keys())
|
|
37
|
+
if (!finished.has(id))
|
|
38
|
+
cache.delete(id);
|
|
39
|
+
// The project's own report shows the current run, which is usually one already built above.
|
|
40
|
+
const currentId = currentRun(project)?.state.run_id;
|
|
41
|
+
const report = currentId && runs[currentId] ? runs[currentId] : buildStatusReport(project);
|
|
19
42
|
tracked.clear();
|
|
20
43
|
for (const id of running)
|
|
21
44
|
tracked.add(id);
|
|
@@ -31,6 +54,7 @@ function fsWatch(dir, onChange) {
|
|
|
31
54
|
*/
|
|
32
55
|
export function createStatusWatcher(d) {
|
|
33
56
|
const tracked = new Set();
|
|
57
|
+
const cache = new Map();
|
|
34
58
|
const watch = d.watch ?? fsWatch;
|
|
35
59
|
let lastLine = "";
|
|
36
60
|
let watching = "";
|
|
@@ -41,7 +65,7 @@ export function createStatusWatcher(d) {
|
|
|
41
65
|
let project;
|
|
42
66
|
try {
|
|
43
67
|
project = d.load();
|
|
44
|
-
frame = buildWatchFrame(project, tracked, { allTasks: d.allTasks });
|
|
68
|
+
frame = buildWatchFrame(project, tracked, { allTasks: d.allTasks, cache });
|
|
45
69
|
}
|
|
46
70
|
catch (e) {
|
|
47
71
|
frame = { schema_version: 1, error: e.message };
|