Something went wrong. Try again.
Review the work your AI agents do. CLI + MCP.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120import { describe, it, expect } from "vitest";import { parseAarTestimony } from "../src/parseAar.js";import { classifyHeading } from "../src/anchors.js";
describe("classifyHeading", () => { it("maps intent variants", () => { expect(classifyHeading("What was asked for")).toBe("intent"); expect(classifyHeading("The ask")).toBe("intent"); expect(classifyHeading("What the user reported")).toBe("intent"); }); it("maps claimed-action variants", () => { expect(classifyHeading("What changed")).toBe("claimed_actions"); expect(classifyHeading("Files touched")).toBe("claimed_actions"); expect(classifyHeading("The fix")).toBe("claimed_actions"); expect(classifyHeading("What was built")).toBe("claimed_actions"); }); it("maps negative-space variants, winning over action words they contain", () => { expect(classifyHeading("What I did NOT do")).toBe("negative_space"); expect(classifyHeading("What I did not change")).toBe("negative_space"); expect(classifyHeading("Not changed / follow-ups")).toBe("negative_space"); expect(classifyHeading("Follow-ups")).toBe("negative_space"); expect(classifyHeading("What this does not change")).toBe("negative_space"); }); it("strips leading section numbering", () => { expect(classifyHeading("4. Validation")).toBe("other"); expect(classifyHeading("5b. What I did not change")).toBe("negative_space"); expect(classifyHeading("3. The fix (owner-directed)")).toBe("claimed_actions"); }); it("falls back to other for unrecognized headings", () => { expect(classifyHeading("Segment summary")).toBe("other"); expect(classifyHeading("Why this is better")).toBe("other"); });});
describe("parseAarTestimony", () => { const md = `# After-Action Report — Example
**Branch:** \`claude/example-aB12\`**PR:** #88**Commit:** \`a1b2c3d\`
## What was asked for
Add a pitch-count column to the box score.
## What changed
- Edited \`o27v2/web/box_text.py\` and ran \`pytest o27v2/tests\`.
## What I did NOT do
- Did not touch \`o27v2/web/templates/box.html\`.`;
it("drops front-matter metadata lines (Branch/PR/Commit) as non-claims", () => { const claims = parseAarTestimony(md); const texts = claims.map((c) => c.text); expect(texts.some((t) => /^Branch:/i.test(t))).toBe(false); expect(texts.some((t) => /^Commit:/i.test(t))).toBe(false); expect(texts.some((t) => /^PR:/i.test(t))).toBe(false); });
it("splits a conjoined sentence into separate claims", () => { const claims = parseAarTestimony(md); const texts = claims.map((c) => c.text); expect(texts).toContain("Edited `o27v2/web/box_text.py`"); expect(texts).toContain("ran `pytest o27v2/tests`"); });
it("tags intent / claimed_actions / negative_space sections", () => { const claims = parseAarTestimony(md); const intent = claims.find((c) => c.text.startsWith("Add a pitch-count")); const action = claims.find((c) => c.text === "Edited `o27v2/web/box_text.py`"); const neg = claims.find((c) => c.text.startsWith("Did not touch")); expect(intent?.section).toBe("intent"); expect(intent?.kind).toBe("intent"); expect(action?.section).toBe("claimed_actions"); expect(action?.kind).toBe("action"); expect(neg?.section).toBe("negative_space"); expect(neg?.kind).toBe("non_action"); });
it("joins soft-wrapped lines within a bullet into one claim", () => { const wrapped = `## What changed
- Updated \`o27v2/web/standings.py\` to batch the per-team record lookup into one query.`; const claims = parseAarTestimony(wrapped); expect(claims.map((c) => c.text)).toContain( "Updated `o27v2/web/standings.py` to batch the per-team record lookup into one query", ); // no stray "query" fragment expect(claims.some((c) => c.text === "query")).toBe(false); });
it("does not extract claims from fenced code blocks", () => { const withCode = `## The fix
\`\`\`pythonfor prow in rows: _decisions[pid] = "W"\`\`\`
Edited \`app.py\`.`; const claims = parseAarTestimony(withCode); expect(claims.some((c) => c.text.includes("_decisions[pid]"))).toBe(false); expect(claims.some((c) => c.text === "Edited `app.py`")).toBe(true); });
it("assigns stable sequential ids", () => { const claims = parseAarTestimony(md); expect(claims[0].id).toBe("claim-001"); expect(claims.every((c, i) => c.id === `claim-${String(i + 1).padStart(3, "0")}`)).toBe( true, ); });});