Skip to content

Yaml frontmatter fix#111

Open
stefanstr wants to merge 10 commits intovasylenko:mainfrom
stefanstr:yaml-frontmatter-fix
Open

Yaml frontmatter fix#111
stefanstr wants to merge 10 commits intovasylenko:mainfrom
stefanstr:yaml-frontmatter-fix

Conversation

@stefanstr
Copy link
Copy Markdown

The original MCP breaks notes using YAML front matter. I added logic ensuring that YAML remains at the beginning of the note for the notes using it.

Stefan Stryjecki and others added 10 commits April 25, 2026 09:10
…ntax helpers

parseFrontmatter detects YAML frontmatter only when --- is line 1 and a
closing --- exists, preventing horizontal rules in note bodies from being
misidentified. formatTagsAsInlineSyntax extracts the tag-formatting logic
from applyNoteConventions so it can be reused by tool handlers.

Also adds 'replace_all' to BearUrlParams.mode for the upcoming bear-add-tag
frontmatter fix.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tTagsAsInlineSyntax

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When text starts with ---\n...\n---, assemble the final note as
frontmatter → title (H1) → tags → body and pass it as a single text
payload so Bear does not insert the title or tags outside the block.
Notes without frontmatter follow the existing code path unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When a note contains YAML frontmatter, rebuild the note body with tags
inserted after the closing --- so a blind prepend cannot clobber the
block. Notes without frontmatter keep the original prepend behavior.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…dd-tag

Tests require Bear to be running. They create throwaway notes with unique
prefixes, verify frontmatter is preserved correctly, then trash the notes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
API validation confirmed mode=replace_all is documented; no code changes
needed. Commit 26fd648 split into two atomic commits (bear-create-note
and bear-add-tag). FINDINGS.md documents the API verification result and
the discrepancy in TASK.md's expected commit count (7 vs 8).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 28, 2026

@stefanstr is attempting to deploy a commit to the vasylenko's projects Team on Vercel.

A member of the Team first needs to authorize it.

@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
1 Security Hotspot
18.0% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@vasylenko
Copy link
Copy Markdown
Owner

Hi @stefanstr ! Thank you for contributing! I will do my best to review this promptly.

Meanwhile, could you please explain in detail how this pain surfaces to you? How can I reproduce it from my end?

The original MCP breaks notes using YAML front matter

Also, please clean up the leftovers from the coding agent (unless you wanted that to remain on purpose, e.g., for me to review? LMK if so), such as progress file or summary (concise version of that might go to the PR description, btw).

Thanks!

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses a correctness issue where Bear x-callback-url operations could disrupt notes that start with YAML frontmatter, by detecting frontmatter and ensuring subsequent title/tag insertion preserves the frontmatter block at the top of the note.

Changes:

  • Added frontmatter parsing + tag formatting/insertion helpers in note conventions, with unit tests.
  • Updated bear-create-note to assemble a single text payload when frontmatter is present to prevent Bear from inserting content above the YAML block.
  • Updated bear-add-tag to detect frontmatter and avoid clobbering it (using mode=replace_all when needed), plus added system tests and documentation/changelog updates.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/tools/note-tools.ts Adds frontmatter-aware handling in bear-create-note and bear-add-tag to preserve YAML structure.
src/operations/note-conventions.ts Introduces parseFrontmatter, formatTagsAsInlineSyntax, and insertInlineTags helpers.
src/operations/note-conventions.test.ts Adds unit tests covering new helpers and insertion behaviors.
src/infra/bear-urls.ts Extends Bear URL mode typing to include replace_all.
tests/system/frontmatter.test.ts Adds end-to-end/system coverage for frontmatter interactions in create-note and add-tag.
README.md Documents frontmatter behavior and conventions.
CHANGELOG.md Adds unreleased entries describing the fixes.
SUMMARY.md Branch/implementation summary added (reviewed for maintainability impact).
PROGRESS.md Branch progress log added (reviewed for maintainability impact).

Comment thread PROGRESS.md
Comment on lines +1 to +24
# Progress: yaml-frontmatter-fix

## Status: Complete

## What was done

### Task 1: API Validation (FINDINGS.md)
- Fetched official Bear x-callback-url docs
- Confirmed `mode=replace_all` is a documented, supported value for `/add-text`
- Confirmed `/replace-note` does not exist (BRIEF.md was mistaken about this alternative)
- No code changes required

### Task 2: Commit split
- Commit 26fd648 (mixed bear-create-note + bear-add-tag changes) split into two atomic commits
- Note: TASK.md expected 3 commits from 26fd648, but the bear-urls.ts change was already in d86067b; the correct split yielded 2 commits from that mixed change
- Final branch structure: 8 commits on top of main, including this follow-up documentation refresh

### Task 3: Documentation refresh
- SUMMARY.md updated with new commit SHAs, API validation result, resolved blockers
- PROGRESS.md updated (this file)

## Remaining work (for PR author)
- Run system tests with Bear open: `npm run test:system`
- Manual verification: create a frontmatter note via MCP, add a tag, confirm structure in Bear
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

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

PROGRESS.md is tracking branch-specific execution status and references internal task artifacts (e.g., FINDINGS.md) that aren’t present in the repo. This kind of progress log tends to go stale quickly once merged; consider removing it from the repository root or relocating it to a more appropriate place (e.g., PR description or contributor docs) if you want to preserve the narrative.

Suggested change
# Progress: yaml-frontmatter-fix
## Status: Complete
## What was done
### Task 1: API Validation (FINDINGS.md)
- Fetched official Bear x-callback-url docs
- Confirmed `mode=replace_all` is a documented, supported value for `/add-text`
- Confirmed `/replace-note` does not exist (BRIEF.md was mistaken about this alternative)
- No code changes required
### Task 2: Commit split
- Commit 26fd648 (mixed bear-create-note + bear-add-tag changes) split into two atomic commits
- Note: TASK.md expected 3 commits from 26fd648, but the bear-urls.ts change was already in d86067b; the correct split yielded 2 commits from that mixed change
- Final branch structure: 8 commits on top of main, including this follow-up documentation refresh
### Task 3: Documentation refresh
- SUMMARY.md updated with new commit SHAs, API validation result, resolved blockers
- PROGRESS.md updated (this file)
## Remaining work (for PR author)
- Run system tests with Bear open: `npm run test:system`
- Manual verification: create a frontmatter note via MCP, add a tag, confirm structure in Bear
# Progress
This repository does not keep branch-specific progress logs in versioned documentation.
Short-lived implementation notes, task checklists, commit-splitting details, and manual verification steps should be recorded in the pull request description or other contributor workflow materials instead of this file.
Keep repository-root documentation focused on stable, long-term project information.

Copilot uses AI. Check for mistakes.
Comment thread src/tools/note-tools.ts
Comment on lines +273 to +278
const parsed = text ? parseFrontmatter(text) : null;

let url: string;
let pollTitle: string | undefined;

if (parsed?.frontmatter !== null && parsed !== null) {
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

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

The frontmatter detection branch uses a confusing/nullish pattern (const parsed = text ? parseFrontmatter(text) : null and if (parsed?.frontmatter !== null && parsed !== null)). Since parseFrontmatter() always returns an object, consider keeping parsed non-null (e.g., always call it when text is provided) and simplify the condition to a straightforward parsed.frontmatter !== null check to reduce cognitive load and avoid subtle truthiness pitfalls later.

Suggested change
const parsed = text ? parseFrontmatter(text) : null;
let url: string;
let pollTitle: string | undefined;
if (parsed?.frontmatter !== null && parsed !== null) {
const parsed = parseFrontmatter(text ?? '');
let url: string;
let pollTitle: string | undefined;
if (parsed.frontmatter !== null) {

Copilot uses AI. Check for mistakes.
Comment thread src/tools/note-tools.ts
Comment on lines +279 to +284
// Frontmatter path: assemble the full note content so Bear doesn't
// insert a title H1 or tags outside the frontmatter block.
const tagLine = tags ? formatTagsAsInlineSyntax(tags) : '';
const bodySegments: string[] = [];
if (title) bodySegments.push(`# ${title}`);
if (parsed.body) bodySegments.push(parsed.body);
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

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

In the frontmatter path, the tool constructs its own # <title> line and sends only text to Bear (no title URL param). That makes the current inputSchema description for text (“Do not include a title heading — Bear adds it automatically from the title parameter.”) inaccurate for frontmatter notes. Update the tool’s schema/description so callers know that when frontmatter is present the server will manage the H1/title itself (and what to do if the user’s text already contains a heading).

Copilot uses AI. Check for mistakes.
Comment thread SUMMARY.md
@stefanstr
Copy link
Copy Markdown
Author

Hi @stefanstr ! Thank you for contributing! I will do my best to review this promptly.

Meanwhile, could you please explain in detail how this pain surfaces to you? How can I reproduce it from my end?

The original MCP breaks notes using YAML front matter

Also, please clean up the leftovers from the coding agent (unless you wanted that to remain on purpose, e.g., for me to review? LMK if so), such as progress file or summary (concise version of that might go to the PR description, btw).

Thanks!

Hey. First off, apologies, I didn't mean to push it to main just yet, hence the leftovers. Misclicked. Feel free to reject this one or pull from it whatever is useful.

The painpoint is that Bear's X-Callback-URL actions were written before they added YAML support and they break notes with frontmatter. YAML blocks need to be at the start of the note whereas currently, new tags, titles, etc. get injected before them. My additions check whether a note contains YAML, and if it does, it makes sure it stays note-initial. Frontmatter is useful for keeping info on web excerpts and such.

@vasylenko
Copy link
Copy Markdown
Owner

The painpoint is that Bear's X-Callback-URL actions were written before they added YAML support and they break notes with frontmatter. YAML blocks need to be at the start of the note whereas currently, new tags, titles, etc. get injected before them. My additions check whether a note contains YAML, and if it does, it makes sure it stays note-initial. Frontmatter is useful for keeping info on web excerpts and such.

Interesting... Does it behave the same with and without the note structure convention enforced? There is an ENV variable that enforces the MCP server to put tags after the H1 note title.

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 5, 2026

Quality Gate Failed Quality Gate failed

Failed conditions
1 Security Hotspot
18.0% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants