// The tools of the forge module's state `failed-steps` (novox/hq design 47 §83, §84): the read of everything it holds, with the // store's fill against its cap, and the one recovery, dropping a held key, written in the hand-act log before it is done. import type { ToolDefinition } from "@novox/mesh-sdk/tools"; import { callerOf } from "@novox/mesh-sdk/callers"; import type { HandAct } from "@novox/mesh-sdk/views"; import type { FailedSteps } from "../failedsteps.js"; export function failedStepsTools(kept: FailedSteps, acts: (act: HandAct) => Promise): ToolDefinition[] { return [ { name: "git_failed_steps", description: "The failed required steps the forge module holds, by module and fingerprint, each with the run that failed it, the commits it was seen at and why; " + "the `seen` keys (each commit's fingerprints, a commit's with `commit`); and the store's fill against its cap (design 47 §83, §487).", input: { type: "object", properties: { commit: { type: "string", description: "only what names this commit" } } }, run: async (args: Record) => { const commit = typeof args.commit === "string" && args.commit !== "" ? args.commit : undefined; const held = await kept.held(commit); return { failed: held.failed.map((f) => ({ ...f, key: `${f.module}.${f.fingerprint}.${f.step}` })), seen: held.seen, fill: held.fill }; }, }, { name: "git_failed_steps_drop", description: "Drops one held key of the state failed-steps, a failed step by its key (..) or a seen key (seen..), with why; " + "the head it refused merges. Written in the hand-act log first (design 47 §84).", input: { type: "object", required: ["key", "why"], properties: { key: { type: "string", description: "the key, as git_failed_steps shows it" }, why: { type: "string", description: "why it is dropped, in plain words" } }, }, run: async (args: Record) => { const key = typeof args.key === "string" ? args.key.trim() : ""; const why = typeof args.why === "string" ? args.why.trim() : ""; if (!key || !why) throw new Error("git_failed_steps_drop names the key and why"); const by = callerOf(args); try { await acts({ what: `dropped the held ${key} of the forge module's failed-steps`, why: `${why} (${by})`, cause: "failed-step-dropped", verb: "git_failed_steps_drop" }); } catch (err) { throw new Error(`the hand act was not recorded, so nothing was dropped: ${err instanceof Error ? err.message : String(err)}`); } return { dropped: await kept.drop(key), key, why, by }; }, }, { name: "git_seen_expire", description: "Deletes the seen keys of the state failed-steps that are more than 30 days old, the oldest first, at most 100: the removal the forge module does on each step-ended, now, with why. " + "Written in the hand-act log first (design 47 §581).", input: { type: "object", required: ["why"], properties: { why: { type: "string", description: "why it is run now, in plain words" } } }, run: async (args: Record) => { const why = typeof args.why === "string" ? args.why.trim() : ""; if (!why) throw new Error("git_seen_expire says why"); const by = callerOf(args); try { await acts({ what: "deleted the seen keys of the forge module's failed-steps past 30 days", why: `${why} (${by})`, cause: "seen-expired", verb: "git_seen_expire" }); } catch (err) { throw new Error(`the hand act was not recorded, so nothing was deleted: ${err instanceof Error ? err.message : String(err)}`); } const deleted = await kept.expireSeen(); return { deleted, why, by }; }, }, ]; }