4 Commits

Author SHA1 Message Date
Makoto Yamada b3c94cc876 feat(client): render YAML frontmatter in markdown preview (full/diff) (#442)
* docs: add frontmatter samples (#441)

Add before/after markdown pairs covering scalar, array, single-level
nested, and deep-nested YAML frontmatter changes for the frontmatter
preview feature.

* feat(client): add extractFrontmatter helper and YAML deps (#441)

Add js-yaml as a runtime dependency for the frontmatter preview
feature, plus a standalone extractFrontmatter helper that
regex-splits a leading YAML block and safely parses it via the
safe `load()` default.

* feat(client): add FrontmatterTable snapshot component (#441)

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>

* feat(client): render frontmatter in MarkdownFullPreview (#441)

Wire extractFrontmatter and FrontmatterTable into MarkdownFullPreview
so the Full Preview tab renders a two-column key/value snapshot table
above the body for markdown files with YAML frontmatter. Files without
frontmatter continue to render unchanged, preserving existing behavior.

* refactor(client): fetch both base and target markdown blobs (#441)

Restructures MarkdownDiffViewer's preview fetch logic to retrieve both
base and target blobs in parallel via Promise.allSettled, laying the
groundwork for diff-preview frontmatter rendering while keeping
MarkdownFullPreview and MarkdownDiffPreview behavior unchanged.

* feat(client): add computeFrontmatterDiff pure helper (#441)

Adds computeFrontmatterDiff(oldData, newData) which returns per-key
FrontmatterDiffEntry records with status of added / removed /
modified / unchanged. Modified detection uses a canonical stringify
that recursively sorts object keys before JSON.stringify, so
frontmatter key reorderings do not produce false positives. Arrays
preserve their original order (order changes are treated as
modifications), and Date values are normalized via toISOString for
comparison so equal timestamps parsed by js-yaml stay unchanged.

Entry order is new-first (newData Object.keys order) with old-only
keys appended, matching the layout the FrontmatterTable diff mode
will render in the next task.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>

* feat(client): add FrontmatterTable diff mode (#441)

Extend FrontmatterTable with a `mode: 'diff'` variant that consumes
FrontmatterDiffEntry[] from computeFrontmatterDiff and renders per-key
rows in a Key / Before / After 3-column layout. Cell-level coloring
uses the existing diff Tailwind classes: `bg-diff-deletion-bg` on the
Before cell for removed/modified, `bg-diff-addition-bg` on the After
cell for added/modified. added/removed leave the opposite cell empty
so the horizontal comparison stays aligned. Nested values use one
level of recursive indent with a JSON.stringify fallback for deeper
structures.

Prepares the component for MarkdownDiffPreview integration in the
next task.

* feat(client): integrate frontmatter diff into MarkdownDiffPreview (#441)

Wires the already-fetched base/target markdown blobs and computeFrontmatterDiff
into MarkdownDiffPreview so the Diff Preview tab shows a frontmatter diff table
(added/removed/modified rows) for modified/renamed files, all-added rows for
new files, all-removed rows for deleted files, and a labeled snapshot fallback
when only one side is available (partial fetch failure).

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>

* chore(deps): pin js-yaml to v4 and drop unused remark-frontmatter (#441)

js-yaml v5 duplicated the dependency tree since every transitive
consumer (eslint, secretlint, etc.) still resolves to v4. Pin to the
v4 series so pnpm dedupes to a single version; the v4 `load()` API
used by extractFrontmatter is unchanged, so the safety rationale from
#441 still applies.

remark-frontmatter was added to dependencies but never imported —
frontmatter parsing goes through js-yaml directly. Drop it along with
its knip ignoreDependencies entry now that it's gone from
package.json.

Co-authored-by: yoshiko-pg <yoshiko-pg@users.noreply.github.com>

* refactor(client): narrow knip config to specific unused export (#441)

ignoreExportsUsedInFile:true suppressed this class of warning
repo-wide, with no other precedent for that setting in this project.
Remove it and un-export the handful of file-local types/functions it
was masking (FrontmatterTable's renderValue/*Props types,
frontmatterDiff's FrontmatterDiffStatus) so knip can catch this
category of unused export everywhere else too.

Co-authored-by: yoshiko-pg <yoshiko-pg@users.noreply.github.com>

* fix(client): restore Full Preview tab for deleted markdown files (#441)

Fetching base and target blobs separately (for the frontmatter diff)
left hasFullPreview and the Full Preview pane hard-wired to
contents.target, which is intentionally never populated for a deleted
file. As a result, deleted markdown files silently lost the Full
Preview tab that main provides via a single status-aware source.

Derive the relevant content (base for deleted files, target
otherwise) once and use it everywhere hasFullPreview and the preview
pane are computed, plus the effect's refetch condition, restoring the
pre-refactor behavior. Add a regression test asserting the tab
appears and base content renders for a deleted file.

Co-authored-by: yoshiko-pg <yoshiko-pg@users.noreply.github.com>

* feat(client): show clear label when partial preview fetch fails (#441)

#441's acceptance criteria call for falling back to snapshot mode
"with a clear label" when a blob fetch fails. Previously that label
only appeared inside FrontmatterTable, so files without frontmatter
gave no indication that half of the diff was missing.

Track whether exactly one side (base or target) failed to fetch and
surface a plain-text banner in both Diff Preview and Full Preview,
independent of whether frontmatter is present.

Co-authored-by: yoshiko-pg <yoshiko-pg@users.noreply.github.com>

* fix(client): strip frontmatter lines from markdown diff preview

Address review feedback on PR #442: in the diff-preview tab the
frontmatter table was rendered at the top while the raw frontmatter
lines from the diff chunks were still rendered as markdown below it,
turning the `---` delimiters into stray <hr> elements.

When both sides needed for the diff are available, compute the
frontmatter line span for each side and exclude those leading lines
from the preview blocks. Matching is content-verified so a diff that
starts below the frontmatter (leading lines are body content) is left
untouched. Snapshot fallback mode keeps its current behavior.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014svkmsEcukbfT4pAFZJMvL

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: yoshiko-pg <yoshiko-pg@users.noreply.github.com>
2026-08-05 23:10:13 +09:00
yoshiko b908dc3c51 Add Mermaid support for markdown diffs (#247)
* feat(client): render mermaid diagrams in markdown preview

* fix(client): sync mermaid theme with appearance settings
2026-03-13 18:45:20 +09:00
yoshiko c82f4b3c78 feat: jupyter notebook viewer (#192)
* feat: add notebook diff preview

* feat: highlight notebook code cells

* fix(client): refine notebook diff preview
2026-02-04 13:27:15 +09:00
maasa fd012703d3 docs: add markdown all-syntax sample 2026-02-01 09:06:03 +09:00