loop-task 2.1.7 → 2.1.9
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.
|
@@ -22,6 +22,7 @@ export class LoopController extends EventEmitter {
|
|
|
22
22
|
this.remainingDelayMs = null;
|
|
23
23
|
this.logStream = null;
|
|
24
24
|
this.loopPromise = null;
|
|
25
|
+
this._loopActive = false;
|
|
25
26
|
this.sessionStartedAt = null;
|
|
26
27
|
this.runHistory = [];
|
|
27
28
|
this.currentRunStartOffset = 0;
|
|
@@ -50,11 +51,14 @@ export class LoopController extends EventEmitter {
|
|
|
50
51
|
return this._status;
|
|
51
52
|
}
|
|
52
53
|
start() {
|
|
54
|
+
if (this._loopActive)
|
|
55
|
+
return;
|
|
56
|
+
this._loopActive = true;
|
|
53
57
|
this.skippedCount = 0;
|
|
54
58
|
this.logStream?.end();
|
|
55
59
|
this.abortController = new AbortController();
|
|
56
60
|
this.logStream = fs.createWriteStream(this.logPath, { flags: "a" });
|
|
57
|
-
this.loopPromise = this.run();
|
|
61
|
+
this.loopPromise = this.run().finally(() => { this._loopActive = false; });
|
|
58
62
|
if (this.sessionStartedAt === null) {
|
|
59
63
|
this.sessionStartedAt = new Date().toISOString();
|
|
60
64
|
}
|
|
@@ -111,7 +115,6 @@ export class LoopController extends EventEmitter {
|
|
|
111
115
|
this.sessionStartedAt = new Date().toISOString();
|
|
112
116
|
this._resetSchedule = true;
|
|
113
117
|
this._paused = false;
|
|
114
|
-
this._status = "waiting";
|
|
115
118
|
const phase = this.options.offset !== null
|
|
116
119
|
? this.options.offset
|
|
117
120
|
: computePhase(this.id, this.options.interval);
|
|
@@ -122,6 +125,7 @@ export class LoopController extends EventEmitter {
|
|
|
122
125
|
this.resumeResolve = null;
|
|
123
126
|
}
|
|
124
127
|
this.start();
|
|
128
|
+
this._status = "waiting";
|
|
125
129
|
this.emit("resumed");
|
|
126
130
|
return true;
|
|
127
131
|
}
|
|
@@ -136,8 +140,8 @@ export class LoopController extends EventEmitter {
|
|
|
136
140
|
if (needsStart) {
|
|
137
141
|
this._stopAfterRun = true;
|
|
138
142
|
this._paused = false;
|
|
139
|
-
this._status = "running";
|
|
140
143
|
this.start();
|
|
144
|
+
this._status = "running";
|
|
141
145
|
}
|
|
142
146
|
else {
|
|
143
147
|
if (this._paused)
|
package/dist/daemon/index.js
CHANGED
|
@@ -3,7 +3,8 @@ import { TaskManager } from "./managers/task-manager.js";
|
|
|
3
3
|
import { IpcServer } from "./server/index.js";
|
|
4
4
|
import { HttpApiServer } from "./http/server.js";
|
|
5
5
|
import { FileWatcher } from "./watcher/index.js";
|
|
6
|
-
import { writeDaemonPid, removeDaemonPid, writeDaemonSignature, removeDaemonSignature, computeCodeSignature, migrateTasksToJson, migrateLoopsToJson, } from "./state/index.js";
|
|
6
|
+
import { writeDaemonPid, removeDaemonPid, writeDaemonSignature, removeDaemonSignature, computeCodeSignature, migrateTasksToJson, migrateLoopsToJson, setSelfWriteNotifier, } from "./state/index.js";
|
|
7
|
+
import { setProjectSelfWriteNotifier } from "./managers/project-manager.js";
|
|
7
8
|
import { t } from "../shared/i18n/index.js";
|
|
8
9
|
import { daemonLog } from "./daemon-log.js";
|
|
9
10
|
async function main() {
|
|
@@ -37,6 +38,8 @@ async function main() {
|
|
|
37
38
|
fileWatcher.setManagers(manager, taskManager, manager["projectManager"]);
|
|
38
39
|
fileWatcher.start();
|
|
39
40
|
daemonLog(`file watcher started for hot-reloading JSON configs`);
|
|
41
|
+
setSelfWriteNotifier((filePath, content) => fileWatcher.registerSelfWrite(filePath, content));
|
|
42
|
+
setProjectSelfWriteNotifier((filePath, content) => fileWatcher.registerSelfWrite(filePath, content));
|
|
40
43
|
let shuttingDown = false;
|
|
41
44
|
const cleanup = async () => {
|
|
42
45
|
if (shuttingDown)
|
|
@@ -4,6 +4,10 @@ import { daemonLog } from "../daemon-log.js";
|
|
|
4
4
|
import crypto from "node:crypto";
|
|
5
5
|
import { getDataDir, projectsJson } from "../../shared/config/paths.js";
|
|
6
6
|
import path from "node:path";
|
|
7
|
+
let selfWriteNotifier = null;
|
|
8
|
+
export function setProjectSelfWriteNotifier(notifier) {
|
|
9
|
+
selfWriteNotifier = notifier;
|
|
10
|
+
}
|
|
7
11
|
export class ProjectManager {
|
|
8
12
|
constructor() {
|
|
9
13
|
this.projects = new Map();
|
|
@@ -68,7 +72,10 @@ export class ProjectManager {
|
|
|
68
72
|
}
|
|
69
73
|
saveAllProjects() {
|
|
70
74
|
const all = Array.from(this.projects.values());
|
|
71
|
-
|
|
75
|
+
const content = JSON.stringify(all, null, 2);
|
|
76
|
+
writeFileAtomic(projectsJson(), content);
|
|
77
|
+
if (selfWriteNotifier)
|
|
78
|
+
selfWriteNotifier(projectsJson(), content);
|
|
72
79
|
}
|
|
73
80
|
saveProject(project) {
|
|
74
81
|
this.projects.set(project.id, project);
|
|
@@ -5,6 +5,10 @@ import { fileURLToPath } from "node:url";
|
|
|
5
5
|
import { removeIfExists, writeFileAtomic } from "../../shared/fs-utils.js";
|
|
6
6
|
import { getLoopsDir, getTasksDir, getLogsDir, logFile, getPidFile, getSignatureFile, getSocketPath, loopsJson, tasksJson, getDataDir, } from "../../shared/config/paths.js";
|
|
7
7
|
export { getDataDir, getPidFile, getSocketPath } from "../../shared/config/paths.js";
|
|
8
|
+
let selfWriteNotifier = null;
|
|
9
|
+
export function setSelfWriteNotifier(notifier) {
|
|
10
|
+
selfWriteNotifier = notifier;
|
|
11
|
+
}
|
|
8
12
|
function ensureDirs() {
|
|
9
13
|
fs.mkdirSync(getDataDir(), { recursive: true });
|
|
10
14
|
fs.mkdirSync(getLogsDir(), { recursive: true });
|
|
@@ -23,7 +27,10 @@ function readJsonArray(filePath) {
|
|
|
23
27
|
}
|
|
24
28
|
function writeJsonArray(filePath, items) {
|
|
25
29
|
ensureDirs();
|
|
26
|
-
|
|
30
|
+
const content = JSON.stringify(items, null, 2);
|
|
31
|
+
writeFileAtomic(filePath, content);
|
|
32
|
+
if (selfWriteNotifier)
|
|
33
|
+
selfWriteNotifier(filePath, content);
|
|
27
34
|
}
|
|
28
35
|
export function migrateLoopsToJson() {
|
|
29
36
|
ensureDirs();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "loop-task",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.9",
|
|
4
4
|
"description": "Loop engineering toolkit. Run any command on a cadence, in the background, managed from a terminal board. Schedule tests, builds, syncs, or agent prompts.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|