# Changelog > [中文](CHANGELOG.zh.md) · English This project follows [Semantic Versioning](https://semver.org/). Only user-visible functional changes are recorded (no documentation, code refactoring, or build/toolchain adjustments). **Recording rules**: - Sections are fixed to **Breaking → Added → Fixed**, in that order; when a change's section does not exist yet, **add it**; when a section ends up with no entries, **remove it**. - A feature that lands in the current version is recorded once, under **Added**; fixes to that same feature **within the same version** are **not** recorded (they are part of building the feature, not repairs of a shipped behavior). - **Fixed** only records fixes to features from **earlier versions**. - **dsh version adaptations**: when the plugin adapts to a new deepseek-harness version, record one **Added** entry "Adapt to deepseek-harness ``" describing the migration (dependency / symbol / API changes). It means "this plugin version is verified against that dsh version", complementing the [compatibility table](docs/compatibility.md) — the table records which plugin version maps to which dsh version, the CHANGELOG records what the adaptation changed. - **No operational how-to details**: an entry states the feature and links to the matching section (anchor to the heading) of the [user guide](docs/usage.md). Usage instructions live in the guide, not here — if the guide lacks a feature, document it there first, then reference it. - Unreleased changes go under **`## NEXT_VERSION`** at the top; on release, run `npm run changelog:release -- ` — it renames `NEXT_VERSION` to `[] - ` and does **not** create a new one (no empty blocks while nothing is in development). When a change lands, check whether a `NEXT_VERSION` block exists — if not, add one, then record the change under it. ## [0.12.0] - 2026-09-06 ### Added - **AI conflict resolution**: the push-blocked and update-conflict dialogs gain an "AI resolve" action — a conversation is created in the conflicting workspace and the local/base/remote versions of each conflicting note are handed to the model for a semantic merge (undecidable points are asked back via ask_user); when done the AI requests the push through dsh's native approval panel, and the remote is only touched after you confirm. See [docs/ai-conflict.md](docs/ai-conflict.md). - **Note search**: the notes manager gains a search box in its top bar — full-text search across every workspace's notes (titles and bodies, case-insensitive; space-separated keywords combine with AND). Results are grouped by workspace with matched-line snippets and keyword highlighting; clicking a hit opens the note in the editor on that line with the keyword selected. See [docs/usage.md §2 "Searching notes"](docs/usage.md#searching-notes). - The settings panel's Git-mode dropdown now opens the harness-style custom menu (portaled card, check-marked rows, outside-click/Escape dismissal) instead of the OS-native select popup, and text-input borders/focus follow the harness settings form. See [docs/usage.md §6](docs/usage.md#6-the-settings-panel). ### Fixed - Fixed saves stalling 10+ seconds on slow networks: the per-workspace git status requests fired when the manager opens were parallel (on shared-repo mode the server serializes them anyway, so the extra connections just sat parked); together with the auto-pull they could occupy every same-origin browser connection, queueing the save POST behind git fetches. Statuses are now fetched strictly one at a time. - Fixed the git clone being permanently wedged after "merge remote & retry" hit a merge conflict (an uncleaned MERGE_HEAD broke every later sync); the leftover merge is now aborted automatically and the clone recovers. ## [0.11.0] - 2026-09-04 ### Breaking - Removed the unused `gitSuggest` API method (and its client wrapper): nothing in the plugin ever called it, and it exposed workspace paths to any caller. - Removed the `route` config option. The HTTP API prefix is now the fixed constant `/plugins/md-notes` on both sides: the browser frontend always hardcoded it, so overriding the backend prefix only severed the frontend↔backend link. Existing configs carrying a `route` key keep loading (schemastery passes unknown keys through; the value is ignored). ### Added - New `checkUpdate` config (default `true`): set it to `false` and the host never contacts registry.npmjs.org — for offline or managed deployments the update check used to be an unconditional outbound call. ### Fixed - Fixed two Git first-sync defects on a fresh device (fresh clone + empty notes dir): ① pulling did nothing — an absent local file read as a local edit (skipped), and the auto-pull short-circuited on "no new remote commits", so remote notes never came down; ② pushing from that state mirror-deleted the ENTIRE remote without confirmation. The last-synced baseline is now empty until the first completed sync (a marker persisted inside the clone's `.git/`, never committed): the first pull brings all remote notes down, and the first push blocks with remote-changed asking for confirmation. - Fixed the sidebar footer entries squeezing/overflowing each other ([#2]): dsh's `.footerActions` lays its `width:100%` children (the default-bundled cordis entry and the notes entry) out in one non-wrapping row. The plugin now stacks them via a `[data-slot]`-anchored rule — one declarative `