import { test } from "node:test"; import assert from "node:assert/strict"; import { formatAgents, formatInbox, formatTasks, formatTrail } from "../src/format.mjs"; test("empty views say so", () => { assert.equal(formatInbox([]), "inbox: empty\n"); assert.equal(formatAgents([]), "agents: no role is claimed\n"); assert.equal(formatTasks([]), "tasks: none\n"); }); // Row 277 (#1782, C2): the held thread claims follow the role lines, each marked `thread`. test("agents adds a thread line for each held thread claim, after the roles", () => { const roles = [{ role: "coder", holder_run: "coder-run", harness: "pi", at: "2026-10-22T05:00:00Z" }]; const threads = [{ thread: "t-1", instance: "assistant", holder_run: "assistant-run", harness: "pi", at: "2026-10-22T05:01:00Z" }]; assert.equal( formatAgents(roles, threads), "coder coder-run pi since 2026-10-22T05:00:00Z\nthread t-1 assistant assistant-run pi since 2026-10-22T05:01:00Z\n", ); assert.equal(formatAgents([], threads), "agents: no role is claimed\nthread t-1 assistant assistant-run pi since 2026-10-22T05:01:00Z\n"); assert.equal(formatAgents(roles), formatAgents(roles, [])); }); test("the trail keeps the broker's order and names a decision's task without its rows", () => { const rows = [ { at: "2026-10-08T10:00:00Z", table: "decisions", seq: 4, id: "d-1", class: "gated", action: "deploy", route_to: "human", blocking: 1, question: "Ship?", task_ref: "vikunja:1/7" }, { at: "2026-10-08T09:00:00Z", table: "events", seq: 2, kind: "decision.raised", actor_role: "coder" }, { at: "2026-10-08T11:00:00Z", table: "decision_events", seq: 1, op: "resolved", choice: "yes", by: "jason", via: "cli" }, ]; const lines = formatTrail("d-1", rows).trimEnd().split("\n"); assert.deepEqual(lines.slice(1, 4).map((l) => l.split(" ")[1]), ["decisions#4", "events#2", "decision_events#1"]); assert.match(lines[1], /gated deploy → human \(blocking\): Ship\?/); assert.match(lines[3], /resolved choice yes by jason via cli/); assert.deepEqual(lines.slice(-2), ["task: vikunja:1/7", "follow with: mosaic trail vikunja:1/7"]); assert.doesNotMatch(formatTrail("vikunja:1/7", rows), /follow with/); }); test("tasks print the tracker fields the snapshot carries", () => { assert.equal(formatTasks([{ task_ref: "vikunja:1/7", fields: { title: "Build S4", done: false } }]), "vikunja:1/7 open Build S4\n"); }); test("U4a: store tasks print like tracker tasks, and their trail rows name the write", () => { assert.equal(formatTasks([{ task_ref: "task:3", source: "store", fields: { title: "Plan", state: "in-progress", done: false } }]), "task:3 in-progress Plan\n"); const rows = [ { at: "2026-11-09T10:00:00Z", table: "store_tasks", seq: 1, op: "create", verb: "task.create", revision: 1, by_role: "pm", by_human: null, fields: { title: "Plan" } }, { at: "2026-11-09T11:00:00Z", table: "store_tasks", seq: 2, op: "archive", verb: "tasks.archive", revision: 2, by_role: null, by_human: "jason", fields: { title: "Plan" } }, ]; const lines = formatTrail("task:3", rows).trimEnd().split("\n"); assert.equal(lines[1], "2026-11-09T10:00:00Z store_tasks#1 create task.create r1 by pm Plan"); assert.equal(lines[2], "2026-11-09T11:00:00Z store_tasks#2 archive tasks.archive r2 by jason Plan"); });