openwolf 1.0.0

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.
Files changed (112) hide show
  1. package/LICENSE +663 -0
  2. package/README.md +232 -0
  3. package/dist/bin/openwolf.js +10 -0
  4. package/dist/bin/openwolf.js.map +1 -0
  5. package/dist/dashboard/assets/AISuggestions-DzE-DQkR.js +1 -0
  6. package/dist/dashboard/assets/ActivityTimeline-DGVjujnt.js +1 -0
  7. package/dist/dashboard/assets/AnatomyBrowser-S-2rmYtw.js +1 -0
  8. package/dist/dashboard/assets/BugLog-CG2zDHJc.js +1 -0
  9. package/dist/dashboard/assets/CerebrumViewer-Dlgoy69U.js +1 -0
  10. package/dist/dashboard/assets/CronStatus-DxUF1iW_.js +1 -0
  11. package/dist/dashboard/assets/DesignQC-BGXn_aq8.js +1 -0
  12. package/dist/dashboard/assets/MemoryViewer-CGqkTyvQ.js +1 -0
  13. package/dist/dashboard/assets/ProjectOverview-DlFhu69i.js +1 -0
  14. package/dist/dashboard/assets/TokenUsage-DDsQiVIq.js +68 -0
  15. package/dist/dashboard/assets/index-CzK9GUjV.css +1 -0
  16. package/dist/dashboard/assets/index-PYeNGjkN.js +52 -0
  17. package/dist/dashboard/index.html +16 -0
  18. package/dist/hooks/post-read.js +68 -0
  19. package/dist/hooks/post-write.js +502 -0
  20. package/dist/hooks/pre-read.js +79 -0
  21. package/dist/hooks/pre-write.js +120 -0
  22. package/dist/hooks/session-start.js +76 -0
  23. package/dist/hooks/shared.js +613 -0
  24. package/dist/hooks/stop.js +146 -0
  25. package/dist/src/buglog/bug-matcher.js +3 -0
  26. package/dist/src/buglog/bug-matcher.js.map +1 -0
  27. package/dist/src/buglog/bug-tracker.js +81 -0
  28. package/dist/src/buglog/bug-tracker.js.map +1 -0
  29. package/dist/src/cli/bug-cmd.js +28 -0
  30. package/dist/src/cli/bug-cmd.js.map +1 -0
  31. package/dist/src/cli/cron-cmd.js +106 -0
  32. package/dist/src/cli/cron-cmd.js.map +1 -0
  33. package/dist/src/cli/daemon-cmd.js +177 -0
  34. package/dist/src/cli/daemon-cmd.js.map +1 -0
  35. package/dist/src/cli/dashboard.js +84 -0
  36. package/dist/src/cli/dashboard.js.map +1 -0
  37. package/dist/src/cli/designqc-cmd.js +31 -0
  38. package/dist/src/cli/designqc-cmd.js.map +1 -0
  39. package/dist/src/cli/index.js +149 -0
  40. package/dist/src/cli/index.js.map +1 -0
  41. package/dist/src/cli/init.js +506 -0
  42. package/dist/src/cli/init.js.map +1 -0
  43. package/dist/src/cli/registry.js +93 -0
  44. package/dist/src/cli/registry.js.map +1 -0
  45. package/dist/src/cli/scan.js +39 -0
  46. package/dist/src/cli/scan.js.map +1 -0
  47. package/dist/src/cli/status.js +85 -0
  48. package/dist/src/cli/status.js.map +1 -0
  49. package/dist/src/cli/update.js +414 -0
  50. package/dist/src/cli/update.js.map +1 -0
  51. package/dist/src/daemon/cron-engine.js +300 -0
  52. package/dist/src/daemon/cron-engine.js.map +1 -0
  53. package/dist/src/daemon/file-watcher.js +53 -0
  54. package/dist/src/daemon/file-watcher.js.map +1 -0
  55. package/dist/src/daemon/health.js +23 -0
  56. package/dist/src/daemon/health.js.map +1 -0
  57. package/dist/src/daemon/wolf-daemon.js +294 -0
  58. package/dist/src/daemon/wolf-daemon.js.map +1 -0
  59. package/dist/src/designqc/designqc-capture.js +235 -0
  60. package/dist/src/designqc/designqc-capture.js.map +1 -0
  61. package/dist/src/designqc/designqc-engine.js +141 -0
  62. package/dist/src/designqc/designqc-engine.js.map +1 -0
  63. package/dist/src/designqc/designqc-types.js +5 -0
  64. package/dist/src/designqc/designqc-types.js.map +1 -0
  65. package/dist/src/hooks/post-read.js +69 -0
  66. package/dist/src/hooks/post-read.js.map +1 -0
  67. package/dist/src/hooks/post-write.js +503 -0
  68. package/dist/src/hooks/post-write.js.map +1 -0
  69. package/dist/src/hooks/pre-read.js +80 -0
  70. package/dist/src/hooks/pre-read.js.map +1 -0
  71. package/dist/src/hooks/pre-write.js +121 -0
  72. package/dist/src/hooks/pre-write.js.map +1 -0
  73. package/dist/src/hooks/session-start.js +77 -0
  74. package/dist/src/hooks/session-start.js.map +1 -0
  75. package/dist/src/hooks/shared.js +614 -0
  76. package/dist/src/hooks/shared.js.map +1 -0
  77. package/dist/src/hooks/stop.js +147 -0
  78. package/dist/src/hooks/stop.js.map +1 -0
  79. package/dist/src/scanner/anatomy-scanner.js +260 -0
  80. package/dist/src/scanner/anatomy-scanner.js.map +1 -0
  81. package/dist/src/scanner/description-extractor.js +1007 -0
  82. package/dist/src/scanner/description-extractor.js.map +1 -0
  83. package/dist/src/scanner/project-root.js +42 -0
  84. package/dist/src/scanner/project-root.js.map +1 -0
  85. package/dist/src/tracker/token-estimator.js +20 -0
  86. package/dist/src/tracker/token-estimator.js.map +1 -0
  87. package/dist/src/tracker/token-ledger.js +45 -0
  88. package/dist/src/tracker/token-ledger.js.map +1 -0
  89. package/dist/src/tracker/waste-detector.js +101 -0
  90. package/dist/src/tracker/waste-detector.js.map +1 -0
  91. package/dist/src/utils/fs-safe.js +74 -0
  92. package/dist/src/utils/fs-safe.js.map +1 -0
  93. package/dist/src/utils/logger.js +48 -0
  94. package/dist/src/utils/logger.js.map +1 -0
  95. package/dist/src/utils/paths.js +23 -0
  96. package/dist/src/utils/paths.js.map +1 -0
  97. package/dist/src/utils/platform.js +14 -0
  98. package/dist/src/utils/platform.js.map +1 -0
  99. package/package.json +77 -0
  100. package/src/templates/OPENWOLF.md +135 -0
  101. package/src/templates/anatomy.md +5 -0
  102. package/src/templates/buglog.json +4 -0
  103. package/src/templates/cerebrum.md +22 -0
  104. package/src/templates/claude-md-snippet.md +5 -0
  105. package/src/templates/claude-rules-openwolf.md +15 -0
  106. package/src/templates/config.json +73 -0
  107. package/src/templates/cron-manifest.json +97 -0
  108. package/src/templates/cron-state.json +7 -0
  109. package/src/templates/identity.md +9 -0
  110. package/src/templates/memory.md +4 -0
  111. package/src/templates/reframe-frameworks.md +597 -0
  112. package/src/templates/token-ledger.json +21 -0
@@ -0,0 +1,300 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import { execSync, spawnSync } from "node:child_process";
4
+ import cron from "node-cron";
5
+ import { readJSON, writeJSON, readText, writeText } from "../utils/fs-safe.js";
6
+ import { scanProject } from "../scanner/anatomy-scanner.js";
7
+ import { detectWaste } from "../tracker/waste-detector.js";
8
+ export class CronEngine {
9
+ wolfDir;
10
+ projectRoot;
11
+ logger;
12
+ broadcast;
13
+ scheduledTasks = [];
14
+ failureCounts = new Map();
15
+ constructor(wolfDir, projectRoot, logger, broadcast) {
16
+ this.wolfDir = wolfDir;
17
+ this.projectRoot = projectRoot;
18
+ this.logger = logger;
19
+ this.broadcast = broadcast;
20
+ }
21
+ start() {
22
+ const manifest = this.readManifest();
23
+ for (const task of manifest.tasks) {
24
+ if (!task.enabled)
25
+ continue;
26
+ if (!cron.validate(task.schedule)) {
27
+ this.logger.warn(`Invalid cron schedule for ${task.id}: ${task.schedule}`);
28
+ continue;
29
+ }
30
+ const scheduled = cron.schedule(task.schedule, () => {
31
+ this.executeTask(task).catch((err) => {
32
+ this.logger.error(`Task ${task.id} failed: ${err}`);
33
+ });
34
+ });
35
+ this.scheduledTasks.push(scheduled);
36
+ this.logger.info(`Scheduled task: ${task.name} (${task.schedule})`);
37
+ }
38
+ }
39
+ stop() {
40
+ for (const task of this.scheduledTasks) {
41
+ task.stop();
42
+ }
43
+ this.scheduledTasks = [];
44
+ }
45
+ async runTask(taskId) {
46
+ const manifest = this.readManifest();
47
+ const task = manifest.tasks.find((t) => t.id === taskId);
48
+ if (!task) {
49
+ this.logger.warn(`Task not found: ${taskId}`);
50
+ return;
51
+ }
52
+ await this.executeTask(task);
53
+ }
54
+ readManifest() {
55
+ return readJSON(path.join(this.wolfDir, "cron-manifest.json"), { version: 1, tasks: [] });
56
+ }
57
+ readState() {
58
+ return readJSON(path.join(this.wolfDir, "cron-state.json"), { last_heartbeat: null, engine_status: "running", execution_log: [], dead_letter_queue: [], upcoming: [] });
59
+ }
60
+ writeState(state) {
61
+ writeJSON(path.join(this.wolfDir, "cron-state.json"), state);
62
+ }
63
+ async executeTask(task) {
64
+ const startTime = Date.now();
65
+ this.logger.info(`Executing task: ${task.name}`);
66
+ try {
67
+ await this.runAction(task.action);
68
+ const duration = Date.now() - startTime;
69
+ // Log success
70
+ const state = this.readState();
71
+ state.execution_log.push({
72
+ task_id: task.id,
73
+ status: "success",
74
+ timestamp: new Date().toISOString(),
75
+ duration_ms: duration,
76
+ });
77
+ // Keep last 100 entries
78
+ if (state.execution_log.length > 100) {
79
+ state.execution_log = state.execution_log.slice(-100);
80
+ }
81
+ this.writeState(state);
82
+ this.failureCounts.set(task.id, 0);
83
+ this.broadcast({
84
+ type: "cron_executed",
85
+ task_id: task.id,
86
+ status: "success",
87
+ duration_ms: duration,
88
+ });
89
+ this.logger.info(`Task ${task.name} completed in ${duration}ms`);
90
+ }
91
+ catch (err) {
92
+ const errorMsg = err instanceof Error ? err.message : String(err);
93
+ const duration = Date.now() - startTime;
94
+ const failures = (this.failureCounts.get(task.id) ?? 0) + 1;
95
+ this.failureCounts.set(task.id, failures);
96
+ this.logger.error(`Task ${task.name} failed (attempt ${failures}): ${errorMsg}`);
97
+ if (failures < task.retry.max_attempts) {
98
+ // Retry with backoff
99
+ const delay = this.calculateDelay(task.retry.backoff, task.retry.base_delay_seconds, failures);
100
+ this.logger.info(`Retrying ${task.name} in ${delay}ms`);
101
+ setTimeout(() => {
102
+ this.executeTask(task).catch(() => { });
103
+ }, delay);
104
+ }
105
+ else {
106
+ // Dead letter or skip
107
+ const state = this.readState();
108
+ state.execution_log.push({
109
+ task_id: task.id,
110
+ status: "failed",
111
+ timestamp: new Date().toISOString(),
112
+ duration_ms: duration,
113
+ error: errorMsg,
114
+ });
115
+ if (task.failsafe.dead_letter) {
116
+ state.dead_letter_queue.push({
117
+ task_id: task.id,
118
+ error: errorMsg,
119
+ timestamp: new Date().toISOString(),
120
+ attempts: failures,
121
+ });
122
+ }
123
+ this.writeState(state);
124
+ this.failureCounts.set(task.id, 0);
125
+ }
126
+ this.broadcast({
127
+ type: "cron_executed",
128
+ task_id: task.id,
129
+ status: "failed",
130
+ duration_ms: duration,
131
+ });
132
+ }
133
+ }
134
+ calculateDelay(backoff, baseSec, attempt) {
135
+ const baseMs = baseSec * 1000;
136
+ switch (backoff) {
137
+ case "exponential":
138
+ return baseMs * Math.pow(2, attempt - 1);
139
+ case "linear":
140
+ return baseMs * attempt;
141
+ default:
142
+ return 0;
143
+ }
144
+ }
145
+ async runAction(action) {
146
+ switch (action.type) {
147
+ case "scan_project":
148
+ scanProject(this.wolfDir, this.projectRoot);
149
+ break;
150
+ case "consolidate_memory":
151
+ this.consolidateMemory(action.params?.older_than_days ?? 7);
152
+ break;
153
+ case "generate_token_report":
154
+ this.generateTokenReport();
155
+ break;
156
+ case "ai_task":
157
+ await this.runAiTask(action.params);
158
+ break;
159
+ default:
160
+ throw new Error(`Unknown action type: ${action.type}`);
161
+ }
162
+ }
163
+ consolidateMemory(olderThanDays) {
164
+ const memoryPath = path.join(this.wolfDir, "memory.md");
165
+ const content = readText(memoryPath);
166
+ if (!content)
167
+ return;
168
+ const cutoff = new Date();
169
+ cutoff.setDate(cutoff.getDate() - olderThanDays);
170
+ const lines = content.split("\n");
171
+ const result = [];
172
+ let inOldSession = false;
173
+ let oldSessionLines = [];
174
+ let currentSessionDate = null;
175
+ for (const line of lines) {
176
+ const sessionMatch = line.match(/^## Session: (\d{4}-\d{2}-\d{2})/);
177
+ if (sessionMatch) {
178
+ // Flush previous old session
179
+ if (inOldSession && oldSessionLines.length > 0) {
180
+ const actionCount = oldSessionLines.filter((l) => l.startsWith("|") && !l.startsWith("|--") && !l.startsWith("| Time")).length;
181
+ result.push(`> Consolidated session (${actionCount} actions)`);
182
+ result.push("");
183
+ }
184
+ currentSessionDate = new Date(sessionMatch[1]);
185
+ if (currentSessionDate < cutoff) {
186
+ inOldSession = true;
187
+ oldSessionLines = [];
188
+ result.push(line); // Keep the header
189
+ }
190
+ else {
191
+ inOldSession = false;
192
+ result.push(line);
193
+ }
194
+ continue;
195
+ }
196
+ if (inOldSession) {
197
+ oldSessionLines.push(line);
198
+ }
199
+ else {
200
+ result.push(line);
201
+ }
202
+ }
203
+ // Flush last old session
204
+ if (inOldSession && oldSessionLines.length > 0) {
205
+ const actionCount = oldSessionLines.filter((l) => l.startsWith("|") && !l.startsWith("|--") && !l.startsWith("| Time")).length;
206
+ result.push(`> Consolidated session (${actionCount} actions)`);
207
+ result.push("");
208
+ }
209
+ writeText(memoryPath, result.join("\n"));
210
+ }
211
+ generateTokenReport() {
212
+ const flags = detectWaste(this.wolfDir);
213
+ const ledgerPath = path.join(this.wolfDir, "token-ledger.json");
214
+ const ledger = readJSON(ledgerPath, {});
215
+ ledger.waste_flags = flags;
216
+ ledger.optimization_report = {
217
+ last_generated: new Date().toISOString(),
218
+ patterns: flags.map((f) => f.pattern),
219
+ };
220
+ writeJSON(ledgerPath, ledger);
221
+ }
222
+ hasClaude() {
223
+ try {
224
+ const cmd = process.platform === "win32" ? "where claude" : "which claude";
225
+ execSync(cmd, { stdio: "ignore" });
226
+ return true;
227
+ }
228
+ catch {
229
+ return false;
230
+ }
231
+ }
232
+ async runAiTask(params) {
233
+ if (!this.hasClaude()) {
234
+ throw new Error("Claude CLI not found. Install it from https://claude.ai/download or add it to PATH.");
235
+ }
236
+ const contextParts = [];
237
+ for (const file of params.context_files) {
238
+ const filePath = path.join(this.projectRoot, file);
239
+ try {
240
+ contextParts.push(`--- ${file} ---\n${fs.readFileSync(filePath, "utf-8")}`);
241
+ }
242
+ catch {
243
+ contextParts.push(`--- ${file} --- (not found)`);
244
+ }
245
+ }
246
+ const fullPrompt = `${params.prompt}\n\n---\nContext:\n${contextParts.join("\n\n")}`;
247
+ try {
248
+ // Use spawnSync to pipe prompt via stdin — avoids command-line length limits on Windows
249
+ // claude -p (no argument) reads prompt from stdin
250
+ // Strip ANTHROPIC_API_KEY so claude uses OAuth subscription credentials
251
+ // instead of a potentially depleted API key
252
+ const env = { ...process.env };
253
+ delete env.ANTHROPIC_API_KEY;
254
+ const proc = spawnSync("claude -p --output-format text", {
255
+ input: fullPrompt,
256
+ timeout: 120000,
257
+ encoding: "utf-8",
258
+ cwd: this.projectRoot,
259
+ env,
260
+ stdio: ["pipe", "pipe", "pipe"],
261
+ // shell: true needed on Windows so that claude.cmd is resolved
262
+ shell: true,
263
+ windowsHide: true,
264
+ });
265
+ if (proc.error) {
266
+ throw proc.error;
267
+ }
268
+ if (proc.status !== 0) {
269
+ const stderr = proc.stderr?.trim();
270
+ const stdout = proc.stdout?.trim();
271
+ const errMsg = stderr || stdout || "Unknown error";
272
+ throw new Error(`Exit code ${proc.status}: ${errMsg}`);
273
+ }
274
+ let result = (proc.stdout || "").replace(/\r\n/g, "\n").trim();
275
+ // Strip markdown code fences if present (```markdown ... ``` or ```json ... ```)
276
+ const fenceMatch = result.match(/```[\w]*\n([\s\S]*?)\n```/);
277
+ if (fenceMatch) {
278
+ result = fenceMatch[1].trim();
279
+ }
280
+ // Write result to suggestions.json if it looks like JSON
281
+ try {
282
+ const parsed = JSON.parse(result);
283
+ writeJSON(path.join(this.wolfDir, "suggestions.json"), {
284
+ generated_at: new Date().toISOString(),
285
+ ...parsed,
286
+ });
287
+ }
288
+ catch {
289
+ // Not JSON, might be a cerebrum update
290
+ if (result.includes("## User Preferences") || result.includes("## Key Learnings") || result.includes("# Cerebrum")) {
291
+ writeText(path.join(this.wolfDir, "cerebrum.md"), result);
292
+ }
293
+ }
294
+ }
295
+ catch (err) {
296
+ throw new Error(`claude -p failed: ${err instanceof Error ? err.message : String(err)}`);
297
+ }
298
+ }
299
+ }
300
+ //# sourceMappingURL=cron-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cron-engine.js","sourceRoot":"","sources":["../../../src/daemon/cron-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import { watch } from "chokidar";
4
+ export function startFileWatcher(wolfDir, logger, broadcast) {
5
+ const watcher = watch(wolfDir, {
6
+ ignoreInitial: true,
7
+ ignored: [
8
+ "**/hooks/_session.json",
9
+ "**/*.tmp",
10
+ "**/daemon.log",
11
+ ],
12
+ persistent: true,
13
+ awaitWriteFinish: {
14
+ stabilityThreshold: 500,
15
+ pollInterval: 100,
16
+ },
17
+ });
18
+ watcher.on("change", (filePath) => {
19
+ const relativePath = path.relative(wolfDir, filePath);
20
+ const fileName = path.basename(filePath);
21
+ logger.debug(`File changed: ${relativePath}`);
22
+ try {
23
+ const content = fs.readFileSync(filePath, "utf-8");
24
+ broadcast({
25
+ type: "file_changed",
26
+ file: relativePath,
27
+ content,
28
+ timestamp: new Date().toISOString(),
29
+ });
30
+ }
31
+ catch {
32
+ // File might be in process of being written
33
+ }
34
+ // Hot-reload config
35
+ if (fileName === "config.json") {
36
+ logger.info("Config changed — hot-reload not fully implemented yet");
37
+ }
38
+ // Hot-reload cron manifest
39
+ if (fileName === "cron-manifest.json") {
40
+ logger.info("Cron manifest changed — restart daemon to apply");
41
+ }
42
+ });
43
+ watcher.on("add", (filePath) => {
44
+ const relativePath = path.relative(wolfDir, filePath);
45
+ logger.debug(`File added: ${relativePath}`);
46
+ });
47
+ watcher.on("unlink", (filePath) => {
48
+ const relativePath = path.relative(wolfDir, filePath);
49
+ logger.debug(`File removed: ${relativePath}`);
50
+ });
51
+ logger.info("File watcher started on .wolf/");
52
+ }
53
+ //# sourceMappingURL=file-watcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-watcher.js","sourceRoot":"","sources":["../../../src/daemon/file-watcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAIjC,MAAM,UAAU,gBAAgB,CAC9B,OAAe,EACf,MAAc,EACd,SAAiC;IAEjC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,EAAE;QAC7B,aAAa,EAAE,IAAI;QACnB,OAAO,EAAE;YACP,wBAAwB;YACxB,UAAU;YACV,eAAe;SAChB;QACD,UAAU,EAAE,IAAI;QAChB,gBAAgB,EAAE;YAChB,kBAAkB,EAAE,GAAG;YACvB,YAAY,EAAE,GAAG;SAClB;KACF,CAAC,CAAC;IAEH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,EAAE;QAChC,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAkB,CAAC,CAAC;QAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAkB,CAAC,CAAC;QACnD,MAAM,CAAC,KAAK,CAAC,iBAAiB,YAAY,EAAE,CAAC,CAAC;QAE9C,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAkB,EAAE,OAAO,CAAC,CAAC;YAC7D,SAAS,CAAC;gBACR,IAAI,EAAE,cAAc;gBACpB,IAAI,EAAE,YAAY;gBAClB,OAAO;gBACP,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACpC,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,4CAA4C;QAC9C,CAAC;QAED,oBAAoB;QACpB,IAAI,QAAQ,KAAK,aAAa,EAAE,CAAC;YAC/B,MAAM,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC;QACvE,CAAC;QAED,2BAA2B;QAC3B,IAAI,QAAQ,KAAK,oBAAoB,EAAE,CAAC;YACtC,MAAM,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;QACjE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,EAAE;QAC7B,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAkB,CAAC,CAAC;QAChE,MAAM,CAAC,KAAK,CAAC,eAAe,YAAY,EAAE,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,EAAE;QAChC,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAkB,CAAC,CAAC;QAChE,MAAM,CAAC,KAAK,CAAC,iBAAiB,YAAY,EAAE,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;AAChD,CAAC"}
@@ -0,0 +1,23 @@
1
+ import * as path from "node:path";
2
+ import { readJSON } from "../utils/fs-safe.js";
3
+ export function getHealth(wolfDir, startTime) {
4
+ const cronState = readJSON(path.join(wolfDir, "cron-state.json"), {
5
+ last_heartbeat: null,
6
+ dead_letter_queue: [],
7
+ });
8
+ const manifest = readJSON(path.join(wolfDir, "cron-manifest.json"), { tasks: [] });
9
+ const deadLetterCount = cronState.dead_letter_queue.length;
10
+ let status = "healthy";
11
+ if (deadLetterCount > 0)
12
+ status = "degraded";
13
+ if (deadLetterCount > 3)
14
+ status = "unhealthy";
15
+ return {
16
+ status,
17
+ uptime_seconds: Math.floor((Date.now() - startTime) / 1000),
18
+ last_heartbeat: cronState.last_heartbeat,
19
+ tasks: manifest.tasks.length,
20
+ dead_letters: deadLetterCount,
21
+ };
22
+ }
23
+ //# sourceMappingURL=health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.js","sourceRoot":"","sources":["../../../src/daemon/health.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAU/C,MAAM,UAAU,SAAS,CAAC,OAAe,EAAE,SAAiB;IAC1D,MAAM,SAAS,GAAG,QAAQ,CAGvB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,CAAC,EAAE;QACxC,cAAc,EAAE,IAAI;QACpB,iBAAiB,EAAE,EAAE;KACtB,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,QAAQ,CACvB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,oBAAoB,CAAC,EACxC,EAAE,KAAK,EAAE,EAAE,EAAE,CACd,CAAC;IAEF,MAAM,eAAe,GAAG,SAAS,CAAC,iBAAiB,CAAC,MAAM,CAAC;IAC3D,IAAI,MAAM,GAAyC,SAAS,CAAC;IAC7D,IAAI,eAAe,GAAG,CAAC;QAAE,MAAM,GAAG,UAAU,CAAC;IAC7C,IAAI,eAAe,GAAG,CAAC;QAAE,MAAM,GAAG,WAAW,CAAC;IAE9C,OAAO;QACL,MAAM;QACN,cAAc,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC;QAC3D,cAAc,EAAE,SAAS,CAAC,cAAc;QACxC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM;QAC5B,YAAY,EAAE,eAAe;KAC9B,CAAC;AACJ,CAAC"}