Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 11 additions & 12 deletions src/agent/index-middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ function renderLinks(
return `# ${heading}\n\n${items.join("\n")}`;
}

/** Parses the optional title and description from YAML front matter. */
/** Parses usable optional display metadata from YAML front matter. */
function parseFrontmatter(
content: string,
filePath: string,
Expand All @@ -191,21 +191,20 @@ function parseFrontmatter(
}

const { description, title } = fields as Record<string, unknown>;
if (
description !== undefined &&
(typeof description !== "string" || !description.trim())
) {
throw new Error(`${filePath} YAML description must be a non-empty string.`);
}
if (title !== undefined && typeof title !== "string") {
throw new Error(`${filePath} YAML title must be a string.`);
}
const usableDescription = usableString(description);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice - i like this. makes sense to not fail here.

const usableTitle = usableString(title);
return {
...(description ? { description } : {}),
...(title ? { title } : {}),
...(usableDescription ? { description: usableDescription } : {}),
...(usableTitle ? { title: usableTitle } : {}),
};
}

/** Returns optional front matter text only when it can be rendered in an index. */
function usableString(value: unknown): string | undefined {
if (typeof value !== "string" || !value.trim()) return undefined;
return value;
}

/** Converts an unknown thrown value into a readable message. */
function errorMessage(error: unknown): string {
return error instanceof Error ? error.message : String(error);
Expand Down
25 changes: 16 additions & 9 deletions test/index-middleware.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,20 +151,27 @@ describe("synchronizeWikiIndexes", () => {
}
});

test.each(["123", "[one, two]", "{ text: nested }"])(
"rejects a non-string YAML description: %s",
async (description) => {
const { backend } = await setup();
test.each([
["123", "[one, two]"],
["[one, two]", "{ text: nested }"],
["{ text: nested }", ""],
])(
"falls back when optional title and description are not usable strings: %s / %s",
async (title, description) => {
const { backend, rootDir } = await setup();
await backend.write(
"/openwiki/page.md",
`---\ntype: Reference\ndescription: ${description}\n---\n`,
`---\ntype: Reference\ntitle: ${title}\ndescription: ${description}\n---\n`,
);

await expect(
synchronizeWikiIndexes(backend, "repository"),
).rejects.toThrow(
"/openwiki/page.md YAML description must be a non-empty string.",
await synchronizeWikiIndexes(backend, "repository");

const index = await readFile(
path.join(rootDir, "openwiki/index.md"),
"utf8",
);
expect(index).toContain("- [page](page.md)\n");
expect(index).not.toContain(" - ");
},
);

Expand Down