Fork Horse repository, listed by its owner. Publisher snapshot.

packages/forkhorse-dashboard/test/agent-status-fixtures.ts

Snapshot at 34e3175

Containing directory

3,701 bytes · typescriptView raw
1import type { StateResponse } from "../src/contracts.ts";
2import { fixtureReceipt, fixtureState, HEAD } from "./fixtures.ts";
3
4export const agentStatusScenarios = ["agents-status", "agents-short-activity", "agent-resume", "agent-idle"];
5export const AGENT_STATUS_NOW = Date.parse("2026-10-14T16:00:00Z");
6
7/** Synthetic /state fixtures; relative ages stay useful for light/dark UI capture. */
8export function agentStatusFixtureState(id = "agents-status", now = Date.now()): StateResponse {
9  const state = fixtureState("quiet");
10  state.project.id = id;
11  const at = (minutes: number) => new Date(now - minutes * 60_000).toISOString();
12  const labels = ["blocked", "returned", "failed", "timeout", "couldnt-run", "checking", "review", "approved", "fixture-agent", "racing", "held", "new", "idle", "legacy"];
13  for (const [index, name] of labels.entries()) {
14    const repoName = `fixture--${name}`;
15    const sha = (index + 1).toString(16).repeat(40).slice(0, 40);
16    state.agents.push({ name, ...(name === "legacy" ? {} : { createdAt: at(120 - index) }) });
17    state.forks.push({ agent: name, repoName, head: sha, remote: `https://git.idiot.tax/fixture/${repoName}.git`, createdAt: at(120) });
18    if (["idle", "legacy"].includes(name)) continue;
19    const packet = `fixture-${name}`;
20    state.packets.push({ id: packet, title: `${name} status fixture`, goal: "Inspect the public agent status", paths: [`src/${name}/**`], acceptance: ["Status evidence is truthful"], mode: name === "racing" ? "race" : "standard" });
21    state.claims.push({ agent: name, packet, repoName, paths: [`src/${name}/**`], createdAt: at(name === "new" ? 1 : 90) });
22    if (name !== "new") state.activity.push({ sequence: index + 2, namespace: "fixture", repoName, agent: name, ref: "refs/heads/main", before: HEAD, after: sha, changedPaths: [`src/${name}/index.ts`], eventTimestamp: at(name === "held" ? 45 : 10), recordedAt: at(name === "held" ? 45 : 10) });
23    if (index <= 7) {
24      const receipt = fixtureReceipt(index === 2 ? "failed" : index === 3 ? "timed-out" : index === 4 ? "infrastructure-error" : index === 5 ? "running" : "passed");
25      receipt.startedAt = at(8);
26      receipt.finishedAt = index === 5 ? null : at(7);
27      state.reviews.push({ id: `review-${name}`, agent: name, repoName, packet, sha, base: HEAD, receipt, receiptDigest: receipt.digest,
28        approval: name === "approved" ? { sha, receiptDigest: receipt.digest } : null,
29        stale: false, promoted: false, createdAt: at(9),
30        ...(name === "returned" ? { returned: { at: at(6), reason: "Push a fixture fix" } } : {}) });
31    }
32    if (name === "blocked") state.blockers.push({ id: "fixture-collision", packet, pushingPacket: packet, claimingAgent: name, pushingAgent: name, repoName, sha, paths: [`src/${name}/index.ts`] });
33    if (name === "racing") state.races = [{ packet, status: "open", entrants: [{ agent: name, repoName, claimedAt: at(90), firstPushAt: at(10), reviewRequestedAt: null, receiptPassedAt: null, approvedAt: null, promotedAt: null, place: null, closedAt: null }] }];
34  }
35  // A canonical event bounds the loaded activity; it never becomes an agent push.
36  state.activity.unshift({ sequence: 1, namespace: "fixture", repoName: state.project.repoName, agent: null, ref: "refs/heads/main", before: HEAD, after: HEAD, changedPaths: [], eventTimestamp: at(60), recordedAt: at(60) });
37  state.activity.sort((a, b) => a.sequence - b.sequence);
38  if (id === "agents-short-activity") state.activity = state.activity.filter((event) => Date.parse(event.recordedAt) > now - 30 * 60_000);
39  if (id === "agent-idle") state.claims = state.claims.filter((claim) => claim.agent !== "fixture-agent");
40  return state;
41}
42