Merge remote-tracking branch 'origin/farm/ae7a5593/ttsr-inline-regex-flags-and-scope-quoting'

This commit is contained in:
can1357
2026-07-15 09:54:46 +02:00
11 changed files with 203 additions and 22 deletions
+3
View File
@@ -40,6 +40,9 @@
### Fixed
- Fixed child shell environment filtering to drop launch-directory `.env.local` values that Bun auto-loaded before OMP starts command shells. ([#4723](https://github.com/can1357/oh-my-pi/issues/4723))
### Fixed
- Fixed `parseFrontmatter`'s malformed-YAML fallback corrupting sibling values: one unparseable line (e.g. `scope: "text","thinking"`) forced every value through a raw key/value split that kept literal quotes. Each value is now reparsed independently as YAML, falling back to the raw trimmed string only for the lines that genuinely don't parse ([#4796](https://github.com/can1357/oh-my-pi/issues/4796)).
## [16.3.10] - 2026-07-06
+16 -3
View File
@@ -149,12 +149,25 @@ export function parseFrontmatter(
throw err;
}
// Simple YAML parsing - just key: value pairs
// Simple key: value fallback. Reparse each value on its own so one
// malformed line (e.g. `scope: "text","thinking"`) can't leave sibling
// values wrapped in literal quotes; values that don't parse as YAML fall
// back to the raw trimmed string (issue #4796).
for (const line of metadata.split("\n")) {
const match = line.match(/^([\w-]+):\s*(.*)$/);
if (match) {
frontmatter[match[1]] = match[2].trim();
if (!match) continue;
const raw = match[2].trim();
let value: unknown = raw;
if (raw.length > 0) {
try {
const parsed = YAML.parse(raw);
if (parsed !== null && typeof parsed !== "object") value = parsed;
else if (Array.isArray(parsed)) value = parsed;
} catch {
// keep the raw string
}
}
frontmatter[match[1]] = value;
}
return { frontmatter: normalizeKeys(frontmatter) as Record<string, unknown>, body };
+22
View File
@@ -43,4 +43,26 @@ Body content`;
expect.objectContaining({ err: expect.stringContaining("broken.md") }),
);
});
it("reparses each fallback value so one malformed line can't corrupt its siblings", () => {
// `scope: "text","thinking"` is not valid YAML, forcing the line-by-line
// fallback. The sibling `condition` value must not inherit literal quotes,
// and `enabled` must reparse to a boolean (issue #4796).
const warnSpy = vi.spyOn(logger, "warn").mockImplementation(() => {});
const content = `---
condition: "(?i)pre.existing"
scope: "text","thinking"
enabled: true
---
Body`;
const result = parseFrontmatter(content, { source: "rule.md" });
expect(result.frontmatter.condition).toBe("(?i)pre.existing");
expect(result.frontmatter.enabled).toBe(true);
// The unrecoverable line survives as its raw trimmed string.
expect(result.frontmatter.scope).toBe('"text","thinking"');
expect(result.body).toBe("Body");
expect(warnSpy).toHaveBeenCalled();
});
});