Add tiers, continuation, fetch cooldown, persistent action log, voice read, batch MCP

This commit is contained in:
Fisto
2026-09-11 15:53:06 +02:00
parent 82f78bb2b4
commit 8e8c15e8bc
17 changed files with 669 additions and 139 deletions
+56
View File
@@ -0,0 +1,56 @@
/*
* Veskslop daemon — persistent action log.
*
* Writes one JSON line per event: triggers, commands, replies, and errors.
* The file rotates at a size limit. Secret-looking strings are redacted.
*/
import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, statSync } from "node:fs";
import { dirname } from "node:path";
import { redactValue } from "./communication.js";
export const ACTION_LOG_MAX_BYTES = 5 * 1024 * 1024;
export class ActionLog {
constructor(
private readonly file = process.env.VESKSLOP_ACTION_LOG ?? ".veskslop-actions.jsonl",
private readonly maxBytes = Number(process.env.VESKSLOP_ACTION_LOG_MAX_BYTES ?? ACTION_LOG_MAX_BYTES)
) {
try {
mkdirSync(dirname(this.file), { recursive: true });
} catch {
// the current directory works
}
}
append(entry: Record<string, unknown> & { type: string }) {
const line = JSON.stringify(redactValue({ timestamp: new Date().toISOString(), ...entry }));
try {
if (existsSync(this.file) && statSync(this.file).size + line.length + 1 > this.maxBytes) {
renameSync(this.file, `${this.file}.1`);
}
appendFileSync(this.file, line + "\n");
} catch (error) {
console.error("[action-log] write failed:", error);
}
}
read(limit = 100): unknown[] {
try {
if (!existsSync(this.file)) return [];
const lines = readFileSync(this.file, "utf8").split("\n").filter(Boolean);
return lines.slice(-limit).map(line => {
try {
return JSON.parse(line);
} catch {
return { type: "unparsed", line };
}
});
} catch (error) {
console.error("[action-log] read failed:", error);
return [];
}
}
}