Skip to content

release: v1.1.2 — Obsidian-safe saves and ©/®/™ notes open again - #52

Merged
evangress merged 4 commits into
mainfrom
release/v1.1.2
Nov 10, 2026
Merged

evangress merged 4 commits into
mainfrom
release/v1.1.2

Conversation

@evangress

Copy link
Copy Markdown
Collaborator

Patch release. Everything here is a bug fix. Two of them were data-safety (§3) defects that could change a user's notes on save.

What ships

Saving no longer breaks Obsidian syntax (2e614c2). remark-stringify escaped defensively, so editing and saving a note rewrote [[Note]] as \[\[Note]], ![[img.png]] as !\[\[img.png]] and > [!tip] as > \[!tip]. Obsidian shows those as literal text. It also added backslashes to ordinary prose (figure [1], ~3 cm, snake_case). The new src/editor/escapes.ts removes an escape only when re-parsing proves the document unchanged.

Notes with ©, ® or ™ open again, and keep those symbols on save (62f74c7). They failed to open with RangeError: Invalid array passed to renderSpec. @milkdown/plugin-emoji turned these symbols into emoji nodes that twemoji can't draw. Their serializer also writes nothing, so A © B would have been saved as A B. src/editor/emoji.ts now keeps them as plain text. Upgrading to plugin-emoji 7.23.0 is not an alternative: it fixes the crash but still deletes the symbols on save.

A failed open can no longer leave a broken tab active (62f74c7). After a load throws, the editor's state already holds the half-loaded document while the screen shows the previous note. The failed tab used to stay active, so Save (which doesn't require a dirty tab) could write that text over the file. TabManager.setActive now restores and reloads the previous tab. Opens from the sidebar, a second launch, or a drop now report the error instead of failing with no message.

Release prep (release: v1.1.2). Version bumped in package.json, tauri.conf.json and Cargo.toml/.lock. The README download table, SECURITY.md, the bug-report template and the landing page now point at v1.1.2, and the CHANGELOG section is dated 2026-11-09.

Verification

  • pnpm typecheck, pnpm test (642 tests, 33 files), pnpm build, and cargo metadata --locked all pass locally.
  • New gates: tests/escapes.test.ts, tests/emoji.test.ts, the obsidianPreserved / escapesKept round-trip classes, ©/®/™ fixtures in preserved that load into a real editor view, and four tabs.test.ts cases for a load that throws. The new tests were confirmed failing before their fixes.
  • On-device (macOS, debug bundle of this branch) against a real Obsidian vault: notes with wikilinks, embeds and callouts saved with only the typed word changed. Toril symbol test.md and a 1,900-word bookmarks note containing ® both open, and an edit-and-save kept ®/™/© byte-exact.
  • Not covered: Windows/WebView2 and Linux were not run by hand, and nothing here touches the updater or installer paths.

To release after merging

  1. Merge this PR.
  2. Tag the merge commit on main and push the tag. release.yml builds the installers and uses the ## [v1.1.2] CHANGELOG section as the release body:
git checkout main && git pull && git tag v1.1.2 && git push origin v1.1.2

v1.1.0 and v1.1.1 installs will be offered this through the updater, since the minisign key secrets are already in place.

🤖 Generated with Claude Code

evangress and others added 4 commits November 9, 2026 21:43
remark-stringify escapes every `[`, `*`, `_` and `~` defensively. For an
Obsidian vault that is destructive: saving an edited note rewrote
`[[Note]]` as `\[\[Note]]`, `![[img.png]]` as `!\[\[img.png]]` and
`> [!tip]` as `> \[!tip]`, which Obsidian renders as literal text. It also
rewrote ordinary prose (`figure [1]`, `~3 cm`, `snake_case`).

src/editor/escapes.ts removes each escape only when re-parsing proves the
document unchanged: per-block bisection (memoized), then one whole-document
parse as the proof, with a bounded whole-document fallback. It never
re-implements CommonMark's escaping rules.

Gates: tests/escapes.test.ts (search, fallback, parse budget, 200-case
property over the real parser) and new obsidianPreserved / escapesKept
classes plus a repair fixture in roundtrip.test.ts.

Also adds Track H (hardening), Track M (medical & radiology students) and
§9 (unplaced value areas) to ROADMAP.md, and fixes a stale README line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cape fix

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Any note containing ©, ® or ™ failed to open with "RangeError: Invalid
array passed to renderSpec". @milkdown/plugin-emoji's remark step splits
text on emoji-regex, which matches those symbols, but twemoji leaves them
as plain text, so the resulting emoji node's toDOM hands ProseMirror a
Text node (rejected since prosemirror-model 1.25.5). Its toMarkdown also
writes only an <img>'s title, so a save would have deleted the symbols:
"A © B" became "A  B". plugin-emoji 7.23.0 fixes the crash but not the
deletion, so upgrading alone would trade an open error for silent loss.

src/editor/emoji.ts is now the one emoji stack (app and gates import it)
and adds a remark step that turns any emoji node twemoji did not draw as
an image back into text. Emoji-presentation forms (©️ ®️ ™️) are unchanged.

The failed open also left the new tab active while the editor still showed
the previous note, with its state already replaced by the half-loaded
document; Save needs no dirty flag, so it could write that over the file.
TabManager.setActive now restores and reloads the previous tab when
onActivate throws, never flushes into the failed tab, and rethrows.
openPath drops the never-activated tab, loadIntoEditor resets `loading`
in a finally, and sidebar/second-launch/drop opens report the failure
instead of rejecting unhandled.

Gates: tests/emoji.test.ts, two round-trip `preserved` fixtures that mount
a view, and four tabs tests for a throwing activation; all red before.
Verified on-device against ~/toril-test-vault.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bump to 1.1.2 (package.json, tauri.conf.json, Cargo.toml/lock), point the
README downloads, SECURITY.md, the issue template and the landing page at
the new version, and date the CHANGELOG section that becomes the release
body. The README note telling v1.1.0 Mac users to get "v1.1.1 or later"
is historical and stays as written.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@evangress
evangress merged commit 4e8df95 into main Nov 10, 2026
9 checks passed
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.

1 participant