Address PR review feedback (#2003)
- parseInsightsContent: append continuation lines to the previous bullet so multiline insights render in full instead of truncating after the first line - .memory-insight-item: white-space: pre-wrap so continuation breaks display - regression tests for per-bullet parsing, counts, and multiline continuations Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -213,6 +213,8 @@ bare border-left text rows, matching the InsightsView card language.
|
||||
font-size: 13px;
|
||||
color: var(--text);
|
||||
line-height: 1.5;
|
||||
/* Multiline insights keep their continuation-line breaks (PR #2003 review). */
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -81,12 +81,24 @@ function parseInsightsContent(content: string | null): ParsedInsightCategory[] {
|
||||
.replace(/<!--[\s\S]*?-->/g, "")
|
||||
.trim();
|
||||
|
||||
// Extract bullet points: filter bullet lines first, then strip the prefix
|
||||
/*
|
||||
FNXC:MemoryView 2026-07-11-01:00:
|
||||
PR #2003 review: an insight can span multiple lines (one bullet followed by
|
||||
continuation text). Bullet lines start a new item; non-empty non-bullet lines
|
||||
append to the previous item instead of being dropped, so multiline insights
|
||||
render in full rather than silently truncating after the first line.
|
||||
*/
|
||||
const items = body
|
||||
.split("\n")
|
||||
.map((line) => line.trim())
|
||||
.filter((line) => /^[-*]\s+/.test(line))
|
||||
.map((line) => line.replace(/^[-*]\s+/, ""));
|
||||
.reduce<string[]>((acc, line) => {
|
||||
if (/^[-*]\s+/.test(line)) {
|
||||
acc.push(line.replace(/^[-*]\s+/, ""));
|
||||
} else if (line.length > 0 && acc.length > 0) {
|
||||
acc[acc.length - 1] = `${acc[acc.length - 1]}\n${line}`;
|
||||
}
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
if (items.length > 0 || body.length > 0) {
|
||||
categories.push({
|
||||
|
||||
@@ -158,6 +158,50 @@ describe("MemoryView", () => {
|
||||
);
|
||||
});
|
||||
|
||||
/*
|
||||
FNXC:MemoryView 2026-07-11-01:00:
|
||||
PR #2003 regression tests for insight parsing: bullets must parse into individual items
|
||||
(the pre-fix parser stripped "- " before filtering for it, collapsing categories into one
|
||||
blob), and a bullet's continuation lines must stay attached to that bullet instead of
|
||||
being dropped.
|
||||
*/
|
||||
it("parses each markdown bullet into its own insight item with the correct count", async () => {
|
||||
mockUseMemoryData.mockReturnValue(
|
||||
createMemoryData({
|
||||
insightsExists: true,
|
||||
insightsContent: "## Patterns\n<!-- extraction marker -->\n- First insight\n- Second insight\n\n## Pitfalls\n- Third insight",
|
||||
}),
|
||||
);
|
||||
|
||||
render(<MemoryView addToast={vi.fn()} />);
|
||||
await userEvent.click(screen.getByRole("tab", { name: "Insights" }));
|
||||
|
||||
expect(screen.getByText("First insight")).toBeInTheDocument();
|
||||
expect(screen.getByText("Second insight")).toBeInTheDocument();
|
||||
expect(screen.getByText("Third insight")).toBeInTheDocument();
|
||||
// Total Insights stat counts individual bullets, and extraction-marker comments are excluded.
|
||||
expect(screen.getByText("3")).toBeInTheDocument();
|
||||
expect(screen.queryByText(/extraction marker/)).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("keeps continuation lines attached to their bullet for multiline insights", async () => {
|
||||
mockUseMemoryData.mockReturnValue(
|
||||
createMemoryData({
|
||||
insightsExists: true,
|
||||
insightsContent: "## Patterns\n- Multiline insight head\n continuation detail line\n- Plain insight",
|
||||
}),
|
||||
);
|
||||
|
||||
render(<MemoryView addToast={vi.fn()} />);
|
||||
await userEvent.click(screen.getByRole("tab", { name: "Insights" }));
|
||||
|
||||
expect(screen.getByText(/Multiline insight head/)).toBeInTheDocument();
|
||||
expect(screen.getByText(/continuation detail line/)).toBeInTheDocument();
|
||||
expect(screen.getByText("Plain insight")).toBeInTheDocument();
|
||||
// The continuation belongs to the first bullet: still exactly 2 insights in the Total stat.
|
||||
expect(document.querySelector(".memory-stat-value")?.textContent).toBe("2");
|
||||
});
|
||||
|
||||
it("shows read-only warning after backend resolves as non-writable", () => {
|
||||
mockUseMemoryData.mockReturnValue(
|
||||
createMemoryData({
|
||||
|
||||
Reference in New Issue
Block a user