singularity-forge/src/tests/cli-logs-tail.test.ts
2026-05-05 14:31:16 +02:00

111 lines
2.5 KiB
TypeScript

import assert from "node:assert/strict";
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { test } from "vitest";
import {
collectRecentLogEvents,
formatMergedLogEvent,
getProjectSessionKey,
} from "../cli-logs.js";
function jsonl(entries: unknown[]): string {
return entries.map((entry) => JSON.stringify(entry)).join("\n") + "\n";
}
test("sf logs tail routes merged sources with expected prefixes", () => {
const root = mkdtempSync(join(tmpdir(), "sf-logs-tail-test-"));
const project = join(root, "project");
const sfHome = join(root, ".sf-home");
try {
mkdirSync(join(project, ".sf", "activity"), { recursive: true });
mkdirSync(
join(sfHome, "agent", "sessions", getProjectSessionKey(project)),
{ recursive: true },
);
writeFileSync(
join(project, ".sf", "notifications.jsonl"),
jsonl([
{
ts: "2026-04-28T10:00:00.000Z",
severity: "info",
message: "Notification ready",
},
]),
);
writeFileSync(
join(
sfHome,
"agent",
"sessions",
getProjectSessionKey(project),
"2026-04-28T10-00-01_sess.jsonl",
),
jsonl([
{
type: "message",
timestamp: "2026-04-28T10:00:01.000Z",
message: {
role: "assistant",
timestamp: 1777370401000,
content: [
{ type: "text", text: "Working on it" },
{ type: "toolCall", name: "Read" },
],
stopReason: "toolUse",
},
},
]),
);
writeFileSync(
join(project, ".sf", "activity", "001-execute-task-M001-S01-T01.jsonl"),
jsonl([
{
type: "message",
timestamp: "2026-04-28T10:00:02.000Z",
message: {
role: "assistant",
timestamp: 1777370402000,
content: [{ type: "toolCall", name: "Bash" }],
stopReason: "toolUse",
},
},
]),
);
writeFileSync(
join(project, ".sf", "audit-log.jsonl"),
jsonl([
{
ts: "2026-04-28T10:00:03.000Z",
severity: "error",
component: "engine",
message: "Audit failure",
},
]),
);
const output = collectRecentLogEvents({
basePath: project,
sfHome,
limit: 10,
})
.map(formatMergedLogEvent)
.join("");
assert.match(output, /\[notif\] Notification ready/);
assert.match(
output,
/\[session\] assistant: Working on it \| tools: Read \| stop: toolUse/,
);
assert.match(output, /\[activity\] tools: Bash \| stop: toolUse/);
assert.match(output, /\[audit\] \[engine\] Audit failure/);
} finally {
rmSync(root, { recursive: true, force: true });
}
});