diff --git a/src/prd.mjs b/src/prd.mjs index 1681e85..cd4713f 100644 --- a/src/prd.mjs +++ b/src/prd.mjs @@ -39,6 +39,10 @@ function today() { return new Date().toISOString().slice(0, 10); } +function yamlString(value) { + return JSON.stringify(String(value ?? "")); +} + function gitEmail(root) { try { return execSync("git config user.email", { cwd: root, stdio: ["ignore", "pipe", "ignore"] }) @@ -110,7 +114,7 @@ export function renderPrd({ id, title, idea, author }) { return `--- openprd: "${OPENPRD.version}" id: "${id}" -title: ${title} +title: ${yamlString(title)} status: Draft authors: - ${author} diff --git a/test/prd.test.mjs b/test/prd.test.mjs new file mode 100644 index 0000000..b9e5852 --- /dev/null +++ b/test/prd.test.mjs @@ -0,0 +1,15 @@ +import assert from "node:assert/strict"; +import test from "node:test"; + +import { renderPrd } from "../src/prd.mjs"; + +test("renderPrd quotes titles so YAML metacharacters stay valid", () => { + const body = renderPrd({ + id: "0001", + title: 'Ship CLI: handle "quoted" flags', + idea: 'Ship CLI: handle "quoted" flags', + author: "dev@example.com", + }); + + assert.match(body, /^title: "Ship CLI: handle \\"quoted\\" flags"$/m); +});