UNPKG

akm-cli

Version:

akm (Agent Knowledge Manager) — a portable, local-first capability library for AI agents. Discover, load, share, and improve reusable skills, scripts, workflows, and knowledge across any shell-capable coding agent, including Claude Code, OpenCode, and Cur

45 lines (44 loc) • 2.42 kB
// This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. /** Proposal validation and the one content repair applied before promotion. */ import { repairTruncatedDescription } from "../../../core/text-truncation.js"; import { splitFrontmatter } from "../../improve/reflect-noise.js"; import { isRetireProposal } from "../proposal-types.js"; import { runProposalValidators } from "./proposal-validators.js"; /** * Validate a proposal before promotion: it must parse and carry a body, and a * type with a canonical validator runs it. * * A retire proposal (alpha.9 consolidate pair pass) writes no new content — * it deletes an asset that already passed validation when IT was created — * so the content-quality validators (built for new/updated bodies: a * description, lesson shape, reflect size ratio, …) do not apply and are * skipped entirely rather than misreading the empty body as a defect. */ export function validateProposal(proposal) { if (isRetireProposal(proposal)) return { ok: true, findings: [] }; return runProposalValidators(proposal); } /** * Normalize line endings and complete a truncated frontmatter `description` * (`repairTruncatedDescription`, with the body as context). Nothing else: an * earlier repair that deleted body lines gutted any asset documenting * frontmatter. Only a single-line description is repaired: one YAML wrapped * over indented lines (`yaml.stringify` does that past ~80 columns) has a * first line that merely looks truncated. Callers re-validate the result. */ export function repairProposalContent(content) { if (typeof content !== "string" || content.trim() === "") return content; const repaired = content.replace(/\r\n/g, "\n"); const { fmText, body } = splitFrontmatter(repaired); if (fmText === null) return repaired; if (/^description:.*\n[ \t]/m.test(fmText)) return repaired; // The frontmatter block only: a body line starting with `description:` is not the description. const frontmatter = repaired.slice(0, repaired.length - body.length); return (frontmatter.replace(/^(description:[ \t]*)(.*?)(\r?\n)/m, (_match, prefix, rawDesc, nl) => `${prefix}${repairTruncatedDescription(rawDesc.trim(), body)}${nl}`) + body); }