import * as fs from "node:fs"; import * as os from "node:os"; import * as path from "node:path"; import { describe, expect, it } from "vitest"; import { createFableFlowManifest, writeFableFlowManifest } from "./fableflow-manifest.js"; describe("fableflow manifest", () => { it("includes required Fable topology nodes", () => { const manifest = createFableFlowManifest(); const ids = manifest.nodes.map((node) => node.id); expect(ids).toEqual(expect.arrayContaining([ "forgejo", "forgejo-runner", "git-proxy-8099", "deploy-webhook-8098", "agent-site-8084", "feedbackpilot-intake", "work-inbox", "forgejo-intake", "forgejo-writeback", "governance-contract", "agent-chain-workers", "zte-gate", "factory-reconcile", "model-access", "fugu-ultra", "fable-moa", "rsi-canary", ])); }); it("marks 8099 canonical and 8098 legacy/stale", () => { const manifest = createFableFlowManifest(); const canonical = manifest.nodes.find((node) => node.id === "git-proxy-8099")!; const legacy = manifest.nodes.find((node) => node.id === "deploy-webhook-8098")!; expect(manifest.meta.deployAuthority).toBe("8099/deploy via git-proxy"); expect(manifest.meta.noDeploy).toBe(true); expect(canonical.desc).toContain("Canonical guarded deploy route"); expect(legacy.desc).toContain("Legacy/stale visual-only"); expect(legacy.line).toBe("legacy"); }); it("wires intake through governance, verification, and canonical deploy", () => { const manifest = createFableFlowManifest(); const edges = manifest.edges.map((edge) => `${edge.from}>${edge.to}`); expect(edges).toContain("forgejo-intake>governance-contract"); expect(edges).toContain("governance-contract>agent-chain-workers"); expect(edges).toContain("agent-chain-workers>zte-gate"); expect(edges).toContain("factory-reconcile>git-proxy-8099"); expect(edges).toContain("model-access>fugu-ultra"); expect(edges).toContain("model-access>fable-moa"); expect(edges).toContain("fugu-ultra>agent-chain-workers"); expect(edges).toContain("fable-moa>agent-chain-workers"); expect(edges).toContain("deploy-webhook-8098>git-proxy-8099"); }); it("writes JSON manifest", () => { const dir = fs.mkdtempSync(path.join(os.tmpdir(), "fableflow-")); const file = path.join(dir, "manifest.json"); writeFableFlowManifest(file); const manifest = JSON.parse(fs.readFileSync(file, "utf-8")) as ReturnType; expect(manifest.meta.schema).toBe("fable.fableflow.manifest.v1"); expect(manifest.nodes.length).toBeGreaterThan(10); }); });