diff --git a/src/resources/extensions/gsd/preferences.ts b/src/resources/extensions/gsd/preferences.ts index 93ac6f1f0..4d88f0271 100644 --- a/src/resources/extensions/gsd/preferences.ts +++ b/src/resources/extensions/gsd/preferences.ts @@ -224,9 +224,13 @@ export function parsePreferencesMarkdown(content: string): GSDPreferences | null return parseHeadingListFormat(content); } - if (!_warnedUnrecognizedFormat) { + // Warn when a non-empty file exists but lacks frontmatter delimiters (#2036). + if (content.trim().length > 0 && !_warnedUnrecognizedFormat) { _warnedUnrecognizedFormat = true; - console.warn("[parsePreferencesMarkdown] preferences.md exists but uses an unrecognized format — skipping."); + console.warn( + "[GSD] Warning: preferences file has unrecognized format — content does not use YAML frontmatter delimiters (---). " + + "Wrap your preferences in --- fences. See https://github.com/gsd-build/gsd-2/issues/2036", + ); } return null; } diff --git a/src/resources/extensions/gsd/tests/preferences.test.ts b/src/resources/extensions/gsd/tests/preferences.test.ts index 7c263ef26..79aa04ef3 100644 --- a/src/resources/extensions/gsd/tests/preferences.test.ts +++ b/src/resources/extensions/gsd/tests/preferences.test.ts @@ -412,6 +412,16 @@ test("unrecognized format warning is emitted at most once (#2373)", () => { } }); +test("parsePreferencesMarkdown parses heading+list format without frontmatter (#2036)", () => { + // A GSD agent recovery session wrote preferences in markdown heading+list + // format instead of YAML frontmatter. Since the heading+list fallback parser + // was added, this format is now handled gracefully. + const content = "## Git\n\n- isolation: none\n"; + const result = parsePreferencesMarkdown(content); + assert.notEqual(result, null, "heading+list content should be parsed"); + assert.deepStrictEqual(result!.git, { isolation: "none" }); +}); + // ── Experimental preferences ───────────────────────────────────────────────── test("experimental.rtk: true is accepted and stored", () => {