// What the AGENTS.md editor sends and reads. The routes are // `GET` and `PUT /api/agents/{name}/agents-md` (swarm-controller-api's // `AgentsMdView`, `AgentsMdEdit` and `AgentsMdSaved`). import { unifiedDiff } from "./unified-diff.js"; /** What `GET` answers: the text as the agent last published it, and its id. */ export interface Instructions { content: string; /** The git blob id of `content`, which an edit names as its base. */ revision: string; } /** The body of a `PUT`. */ export interface InstructionsEdit { base_revision: string; diff: string; } export function instructionsUrl(agent: string): string { return `/api/agents/${encodeURIComponent(agent)}/agents-md`; } /** An answer of the wrong shape is no answer: the editor shows an error. */ export function parseInstructions(json: unknown): Instructions | null { if (typeof json !== "object" || json === null) return null; const { content, revision } = json as Record; if (typeof content !== "string" || typeof revision !== "string") return null; return { content, revision }; } /** * The `PUT` body that turns `base` into `draft`, or `null` when they are the * same text and there is nothing to save. */ export function editBody( base: Instructions, draft: string, ): InstructionsEdit | null { const diff = unifiedDiff(base.content, draft); return diff === "" ? null : { base_revision: base.revision, diff }; } /** The status the swarm answers a `PUT` with when the file moved on. */ export const STALE_STATUS = 409;