loop-task 2.1.8 → 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,13 +51,14 @@ export class LoopController extends EventEmitter {
|
|
|
50
51
|
return this._status;
|
|
51
52
|
}
|
|
52
53
|
start() {
|
|
53
|
-
if (this.
|
|
54
|
+
if (this._loopActive)
|
|
54
55
|
return;
|
|
56
|
+
this._loopActive = true;
|
|
55
57
|
this.skippedCount = 0;
|
|
56
58
|
this.logStream?.end();
|
|
57
59
|
this.abortController = new AbortController();
|
|
58
60
|
this.logStream = fs.createWriteStream(this.logPath, { flags: "a" });
|
|
59
|
-
this.loopPromise = this.run();
|
|
61
|
+
this.loopPromise = this.run().finally(() => { this._loopActive = false; });
|
|
60
62
|
if (this.sessionStartedAt === null) {
|
|
61
63
|
this.sessionStartedAt = new Date().toISOString();
|
|
62
64
|
}
|
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": {
|