Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
d1efd4a
feat(search): search inside document contents
anbturki Jul 21, 2026
e2538b4
feat(search): show content matches in the sidebar
anbturki Jul 21, 2026
a89b88a
feat(find): find within the open document
anbturki Jul 22, 2026
307c7c3
docs: record search and find-in-document
anbturki Jul 22, 2026
a2502e2
fix(find): repaint when the ranges change, not the match count
anbturki Jul 22, 2026
d92d7c6
feat(search): restrict search to names, contents, or tags
anbturki Jul 22, 2026
7adddcd
feat(search): add a workspace search lens
anbturki Jul 22, 2026
2f5cd5b
fix(search): honour the scope in the results list
anbturki Jul 22, 2026
626fde7
feat(search): find document contents from quick open
anbturki Jul 22, 2026
02677df
fix(explorer): keep the lens tabs inside the sidebar
anbturki Jul 22, 2026
68a5d7a
feat(search): filter quick open by scope
anbturki Jul 22, 2026
e14e902
feat(settings): make the search shortcuts rebindable
anbturki Jul 22, 2026
1a572b7
docs: describe the three search surfaces
anbturki Jul 22, 2026
d20ca73
feat(explorer): make the workspace switcher a dropdown
anbturki Jul 22, 2026
f75ad30
feat(explorer): replace the lens tabs with a vertical rail
anbturki Jul 22, 2026
fed7cb1
docs(mcp): tell agents how to choose a workspace
anbturki Jul 22, 2026
d506ce8
feat(chrome): unify the window chrome into one toolbar
anbturki Jul 22, 2026
9a4bdec
refactor(chrome): move the shared chrome dimensions into their own mo…
anbturki Jul 22, 2026
e3f5545
docs(mcp): require a project-identifying workspace name and reuse
anbturki Jul 22, 2026
f9414e6
feat(chrome): compact the toolbar and ground the workspace switcher
anbturki Jul 22, 2026
8ea2dc6
feat(explorer): collapse three sidebar searches into one
anbturki Jul 22, 2026
77767e5
fix(workspace): stop duplicate slugs resolving to an arbitrary workspace
anbturki Jul 22, 2026
89cbae4
fix(workspace): let a folder's own marker settle its slug
anbturki Jul 22, 2026
99e1634
feat(explorer): keep the lens rail visible when the sidebar collapses
anbturki Jul 22, 2026
b0c4e1d
docs(search): say which surface reads the source and which the page
anbturki Jul 22, 2026
442cb1d
fix(release): declare a macOS floor the app can actually meet
anbturki Jul 22, 2026
501581a
refactor: trim a comment that narrated its own function
anbturki Jul 22, 2026
5963b49
fix(find): stop the find bar matching its own label
anbturki Jul 22, 2026
b9fef94
fix(install): refuse to install on a macOS that cannot run the app
anbturki Jul 22, 2026
baebf87
fix(search): scope cancellation per surface and report a folder that …
anbturki Jul 22, 2026
b9c1ed3
feat(chrome): inset the panels and give the rail the accent colour
anbturki Jul 22, 2026
0d20d86
feat(tasks): let a status group fold away
anbturki Jul 22, 2026
87457eb
feat(explorer): move the workspace controls into the sidebar header
anbturki Jul 22, 2026
3648207
feat(tasks): drive the board from the shared filter
anbturki Jul 22, 2026
5f6ffef
fix(tabs): say a file is gone instead of quoting the filesystem
anbturki Jul 22, 2026
afaf369
test(tabs): restore the load tests lost when the file was overwritten
anbturki Jul 22, 2026
4eb7d75
perf(document): stop re-parsing every open document on a tab switch
anbturki Jul 22, 2026
fee4ff0
refactor(layout): make the split modes a closed set
anbturki Jul 22, 2026
ec2b92b
docs: catch the feature docs up with the sidebar rework
anbturki Jul 22, 2026
73e5011
fix(theme): draw the accent from one definition
anbturki Jul 22, 2026
6cd2ae6
style(core): apply rustfmt to the workspace resolution changes
anbturki Jul 22, 2026
5aaff0c
style(explorer): dim the resting rail labels further
anbturki Jul 22, 2026
bc7fda7
test(mcp): pin the workspace refusals and the naming guidance
anbturki Jul 22, 2026
3f69fba
fix(theme): draw status colours from the theme palette
anbturki Jul 22, 2026
6294ead
fix(theme): point the editor chrome at the app theme
anbturki Jul 22, 2026
7131e50
fix(tasks): leave one refresh control in the sidebar
anbturki Jul 22, 2026
39f06fc
refactor(workspace): report whether a resolution found anything
anbturki Jul 22, 2026
39c8b57
feat(theme): give each accent its own colour, and rebuild the picker
anbturki Jul 22, 2026
f0423c4
feat(tasks): move the task count onto the header row
anbturki Jul 22, 2026
f157f5f
fix(theme): let a dialog dim the page behind it
anbturki Jul 22, 2026
0defd90
test: keep agent worktrees out of the test run
anbturki Jul 22, 2026
8e76e36
fix(mcp): stop an unplaced write landing in the shared workspace
anbturki Jul 22, 2026
ff7931a
feat(tasks): let the tasks lens be shown as a list
anbturki Jul 22, 2026
44a937f
fix(theme): keep the window controls in step with the theme
anbturki Jul 22, 2026
ca5acd9
docs: describe the accents, the task list, and the write refusal
anbturki Jul 22, 2026
b0d8279
fix(ui): restore the hover state on primary buttons
anbturki Jul 22, 2026
b45e34a
fix(chrome): centre the window controls and clear the switcher
anbturki Jul 22, 2026
93a55bf
fix(mcp): refuse an unplaced write wherever the shared workspace exists
anbturki Jul 22, 2026
25ff5c4
docs(mcp): say when an unplaced write is refused
anbturki Jul 22, 2026
003a36c
fix(theme): make slate a slate, the black chip visible, and the caret…
anbturki Jul 22, 2026
5a83d46
fix(layout): stop the whole window scrolling behind the app
anbturki Jul 22, 2026
e97f15d
test(document): pin the editor surviving a theme change
anbturki Jul 22, 2026
7db4a45
test(mcp): cover where an unplaced write is allowed to land
anbturki Jul 22, 2026
c43c369
feat(tasks): open the task board in the main area, with room for columns
anbturki Jul 22, 2026
8d1e4ad
fix: stop the system overriding a chosen theme, and three chrome defects
anbturki Jul 22, 2026
1f05b73
docs: drop the screenshots nothing references
anbturki Jul 22, 2026
96fbfc9
fix(document): remember scroll again in a pane that starts loaded
anbturki Jul 22, 2026
6256670
feat(tasks): drop the explorer beside the full-page board
anbturki Jul 22, 2026
aa4a4fe
test(find): pin that a new query leaves nothing of the last one
anbturki Jul 22, 2026
ca91a7c
docs: retake the screenshots from the demo workspace
anbturki Jul 22, 2026
a278a19
docs: retake the task board shot without the explorer beside it
anbturki Jul 22, 2026
86b4373
fix(tasks): let a card be dragged to another status
anbturki Jul 22, 2026
7da2d5e
feat(tasks): choose the task view from the toolbar
anbturki Jul 22, 2026
a35cacf
feat(tasks): make the list a set of grouped rows
anbturki Jul 22, 2026
d5cee4b
docs: start a changelog, with 0.10.0 written up
anbturki Jul 22, 2026
2648799
docs: describe the task views where they now live
anbturki Jul 22, 2026
02fd91f
fix(toolbar): anchor the search instead of centring it on its neighbours
anbturki Jul 22, 2026
da8a09e
docs: retake the screenshots against the current interface
anbturki Jul 22, 2026
a12abcc
docs(changelog): date the 0.10.0 release
anbturki Jul 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ jobs:
NOTES=$(printf '%s\n' \
'See assets below to download and install.' \
'' \
'> [!IMPORTANT]' \
'> **macOS 11 Big Sur or later is required, with Safari 16.4 or later installed.** DocsReader draws its interface with the system WebView, so the installed Safari decides what it can display: on Big Sur and Monterey, install the latest Safari from Software Update first.' \
'>' \
'> On macOS 10.15 Catalina or earlier, DocsReader cannot run. If a Mac on Catalina offers you this update, do not install it - the new version will not open, and no earlier version works on Catalina either. Update macOS first.' \
'' \
'Install via Homebrew:' \
'```' \
'brew install --cask anbturki/tap/docsreader' \
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/update-homebrew-tap.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ jobs:
desc "Markdown documentation reader"
homepage "https://github.com/anbturki/docsreader"

depends_on macos: ">= :big_sur"

app "DocsReader.app"
binary "#{appdir}/DocsReader.app/Contents/MacOS/docsreader-mcp"

Expand Down
177 changes: 177 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
# Changelog

All notable changes to DocsReader are recorded here.

The format follows [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/),
and DocsReader adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

Nothing yet.

## [0.10.0] - 2026-07-23

> [!IMPORTANT]
> **Agents: a write with no workspace is now refused instead of falling back to the shared personal workspace.**
> If your agent setup relies on writing without naming a workspace, it will start
> getting an error until a workspace covers the folder it works in. See
> Breaking changes below.

> [!IMPORTANT]
> **macOS 11 Big Sur or later is now required**, with Safari 16.4 or later installed.
> Earlier builds claimed to support macOS 10.15 Catalina, which they never could.
> The in-app updater cannot check the system version, so a Mac below Big Sur will
> still be offered this update and the installed app will not launch. Update macOS first.

### Breaking changes

- **A write with no `workspace` argument is refused unless a workspace covers where the agent is working.**
Previously such a write fell back to the shared personal workspace at `~/notes`,
creating it if it did not exist, so project work was silently absorbed into a
folder nobody chose. Now the write is refused with an error listing the
workspaces that do exist; clients that support prompting are asked to pick one
instead. Affects `write_doc`, `update_doc`, `set_status`, `set_phase`, `archive`,
`rename_doc`, `delete_doc`, `write_task`, `update_task`, `set_task_status` and
`write_memory`. Passing `workspace` explicitly always works, including when it
names the personal workspace: that is a choice rather than a drift.
- **Reads are unchanged.** `list_docs`, `read_doc`, `search_docs`, `list_tasks` and
`search_memory` still fall back to the personal workspace, so a session with
nothing set up can still look around.
- **Only `init_workspace` creates a workspace.** Create-on-first-write is gone. To
restore the old behaviour for a project, run `init_workspace` once against that
project and use the slug it reports.
- **The minimum supported macOS is 11 Big Sur** (previously declared 10.15 Catalina).
The installer now stops on anything older and warns below macOS 13.3, which is
the first release that already carries the required Safari; on Big Sur and
Monterey, update Safari before launching. The Homebrew cask declares the same
requirement.

### Added

- **Search inside document contents.** The sidebar search now matches the text
inside documents as well as names, titles and tags. Results are grouped by
document with a match count each, expand to every matching line in context, and
collapse individually.
- **One search for the whole sidebar.** A magnifier in the sidebar header reveals
the search box; the query applies to whichever lens is showing, including Tasks,
where it matches task titles and ids.
- **Scope filters.** Any search can be narrowed to Files, Contents or Tags, from
the sidebar and from quick open.
- **Content matches in quick open.** Quick open lists matches from inside
documents beneath the file-name matches, each with the line that matched, across
every open workspace. File-name ranking still resolves instantly.
- **Find in the open document.** A find bar scoped to the focused pane highlights
every match, steps through them with Enter and Shift+Enter, centres the focused
match and reads a running count. Rendered math is found by its source through
workspace search rather than in the rendered page.
- **Rebindable search shortcuts.** Quick open, find in document and workspace
search are all editable in Settings and take effect without a restart. A cleared
or unusable binding falls back to its default rather than leaving the action
unreachable.
- **Tasks in the main area.** Tasks open as a full-window tab with room for
side-by-side status columns, shown as a board or as one flat list, chosen from
the toolbar while that tab is showing.
- **Collapsible status groups.** Each status folds to its header row, keeping its
count visible, remembered per workspace. A folded status opens itself while a
search or filter has a match inside it, and a card can still be dropped onto it.
- **Task filters in the sidebar header.** Priority and label filters live in a
popover beside search, and the task count moves onto the header row.
- **A sidebar that collapses to its rail.** Collapsing now leaves the lens rail in
place, so every lens stays one click away; the collapse control lives on the rail
and keeps one position in both states.
- **A workspace switcher menu.** The switcher is a single control naming the active
workspace, opening a list of every workspace with add and remove.
- **Four more accent colours** - teal, magenta, bronze and black - and a rebuilt
appearance picker that shows each scheme as a miniature interface and each accent
as a labelled chip.

### Changed

- **One toolbar across the window.** The separate document toolbar and sidebar
header are replaced by a single bar spanning the full window width, holding the
workspace switcher. Nothing in it moves as you switch tabs: the search sits at
a fixed point rather than drifting with the length of the path beside it or
with a control appearing for the open tab.
- **Lenses moved to a vertical rail** down the left edge, each an icon with its
name, so adding lenses no longer reflows the sidebar. The sidebar is wider to
pay for it, leaving the content column wider than the whole sidebar used to be.
- **The panels are inset as a set**, the document card trades its shadow for a
hairline border and a smaller corner radius, and the rail carries the chosen
accent as a solid fill that reads the same in light and dark.
- **The sidebar header is a row of controls** - search, filter, refresh and any
count the lens publishes - with no title of its own. The footer file count is
gone; the link back to hidden files stays.
- **Refresh moved from the window toolbar into the sidebar header**, and one
control now both rescans the workspace and reloads whatever the lens is showing.
- **The editor follows the app theme.** Editing surfaces take their colours from
the same theme and accent as the reader, instead of a pasted-in palette that
tracked neither, so greys, the caret and inline code stop changing between
reading and editing.
- **Status colours come from the theme.** Git badges, the external-change banner
and its tab dot, diff rows and the up-to-date line all draw from the theme's
palette rather than their own hard-coded shades. Their hues stay independent of
the accent on purpose, so a green accent cannot turn a removed diff line green.
- **Slate reads as a slate.** It was drawn at full saturation on a blue hue, which
made it a second Blue in the picker. Every other stored accent choice renders
exactly as before.
- **The document explorer is hidden beside a full-window task board**, which is
already a view of the whole workspace. The sidebar toggle still works, and an
ordinary document still opens with the sidebar the way it was left.
- **Agent guidance for choosing a workspace.** The onboarding resource and the tool
descriptions now set out list, reuse, create as the order, ask for a name that
identifies the project rather than "Notes" or "Docs", state that a git repository
is a valid location and that only the notes folder is written, and say that an
already-a-workspace answer means the workspace is ready to use.
- **`init_workspace` reports the slug it assigned.** A slug that another workspace
already holds is refused, naming the folder it collides with; a slug derived from
a folder name gets a suffix instead. Use the returned value on later calls.
- **Workspace listing reflects what is on disk.** Each workspace's slug is read
from its own folder, so editing it takes effect, and workspaces whose folder no
longer exists are dropped from the list instead of being offered.
- **Remembered tabs use a new stored shape.** Upgrading keeps your open tabs.
Downgrading does not: a build older than 0.10.0 reads the new store as empty and
starts with no tabs.

### Removed

- **Create-on-first-write.** A write no longer creates the workspace it lands in;
see Breaking changes above.
- The file count in the sidebar footer, and the separate free-text filter on the
task board, which the one sidebar search now covers.

### Fixed

- The window's close, minimise and zoom controls were drawn for the wrong
appearance when the chosen theme differed from the system one, leaving them
invisible against the toolbar until hovered.
- Choosing a light or dark theme no longer gets overridden when the system
switches its own appearance, so the app stops turning dark at sunset.
- The whole window could scroll behind the app: a long document grew the page
instead of scrolling inside its pane, producing a second scrollbar and carrying
the tab bar off the top of the window.
- Primary buttons had no hover state anywhere in the app.
- A task card could not be dragged onto another status on macOS: the drag started
and ended but no column ever saw it.
- Dialogs and sheets did not dim the page behind them, so the content behind
competed with the dialog in front.
- Scroll position stopped being remembered in a pane that opened with its document
already loaded, which is what toggling the split does. The same fault dropped the
reader back at a stale position each time an agent rewrote the open file.
- A tab could sit on Loading forever when a read settled at exactly the wrong
moment.
- Opening a file that had been deleted showed a raw filesystem error, absolute path
and error number included, instead of saying the file is gone and pointing at
refreshing the workspace.
- Switching between two already-open tabs re-parsed and re-rendered every open
document, so the switch was visibly slow and the outgoing document lingered.
- A stray vertical scrollbar painted over the tab titles, and in a split view sat
on top of the active tab's name.
- Two workspaces could carry the same slug, and every call naming it went to
whichever registered first, so work landed in the wrong folder and reported
success. An ambiguous slug is now reported rather than guessed.
- Every unnamed workspace showed as "notes" in the switcher, because managed
workspaces all live in a folder of that name. They are now labelled by the
project that contains them.

[Unreleased]: https://github.com/anbturki/docsreader/compare/v0.10.0...HEAD
[0.10.0]: https://github.com/anbturki/docsreader/compare/v0.9.2...v0.10.0
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,11 @@ Needs `docsreader-mcp` on your PATH and `jq`. Full setup in the [plugin README](
| --- | --- |
| **Rich rendering** | GitHub-flavored Markdown, KaTeX math, Mermaid diagrams, Shiki highlighting across twelve themes |
| **Interactive checklists** | Toggle any checkbox from the rendered view; the change writes back to the file |
| **Five lenses** | Tree, Recent, Tags, Pinned, and a Tasks kanban board over one library |
| **Five lenses** | Tree, Recent, Tags, Pinned, and Tasks over one library, on a rail the sidebar collapses to |
| **Split view** | Two docs side-by-side or stacked, each with its own tabs and scroll |
| **Full-text search** | Search names, tags, and the text inside documents, from the toolbar's search or the magnifier in the sidebar header; narrow to files, contents, or tags |
| **Open with** | Double-click a `.md` in Finder or "Open With DocsReader" to jump straight to a file or folder |
| **Task board** | To Do / In Progress / Done with drag-to-advance and acceptance-criteria progress, consistent with the MCP |
| **Tasks board or list** | Tasks open full-window as a board of To Do / In Progress / Done columns, or as grouped rows; switch from the toolbar, drag a card to change its status, and see acceptance-criteria progress, all consistent with the MCP |
| **Agent-aware** | Open docs reload live as agents write; on-disk changes surface a diff; git status shows in the tree |
| **Quiet and local** | Minimal chrome, no telemetry, signed updates, notarized on macOS |

Expand All @@ -84,9 +85,12 @@ More views in [docs/FEATURES.md](docs/FEATURES.md).

Manual downloads: `DocsReader_*_universal.dmg` (macOS Intel + Apple Silicon), `DocsReader_*_amd64.AppImage` or `.deb` (Linux), `DocsReader_*_x64-setup.exe` (Windows).

**macOS requirement:** macOS 11 Big Sur or later, with Safari 16.4 or later installed. The app renders in the system WebView, so the installed Safari version decides which CSS features are available. macOS 13.3 Ventura and later ship Safari 16.4 or newer; on Big Sur and Monterey, install the latest Safari from Software Update first.

## More

- **[What's new](https://github.com/anbturki/docsreader/releases)** - release history and notes
- **[CHANGELOG.md](CHANGELOG.md)** - what changed in each version
- **[What's new](https://github.com/anbturki/docsreader/releases)** - downloads for every release
- **[docs/MCP.md](docs/MCP.md)** - connect agents, every tool, the `docsreader://` resources
- **[docs/FEATURES.md](docs/FEATURES.md)** - the full feature list
- **[docs/DEVELOPMENT.md](docs/DEVELOPMENT.md)** - build from source, release process
Expand Down
12 changes: 10 additions & 2 deletions docs/AGENTS-TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,20 @@ the `docsreader` MCP server is registered (DocsReader: Settings → AI agents
This project keeps its knowledge in a DocsReader workspace at `./notes`
(workspace slug: `my-project`), served by the `docsreader` MCP server. Use
its tools instead of writing markdown files by hand: they handle slugs,
frontmatter, status folders, and git staging.
frontmatter, status folders, and git staging (files under `./notes` are added
to the index, never committed, and nothing else in the repo is touched).

- Pass `workspace: "my-project"` on every docsreader call so nothing lands
in the wrong workspace. If a call fails with `workspace_not_found`, create
the workspace once with `init_workspace {path: "<absolute repo root>",
slug: "my-project"}` and retry.
slug: "my-project", name: "My Project"}` and retry. Check
`list_workspaces` first and reuse a match; a reply of "already a DocsReader
workspace" means it exists and is ready, so keep writing there. This repo
being a git repository is not a reason to write elsewhere. The `name` is
what humans pick from in the app, so name it after this project or product
("Acme Billing API"), never "Notes" or "Docs".
- Never track this project's docs or tasks in `~/notes` or another project's
workspace; a label is not a substitute for a workspace.
- Read the `docsreader://onboarding` resource once per session for the full
model.
- Before writing anything, search: `search_memory {query}` for prior facts,
Expand Down
2 changes: 1 addition & 1 deletion docs/DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ cargo build --manifest-path src-tauri/Cargo.toml -p docsreader-mcp

## Releasing

GitHub → Actions → **Cut Release** → enter the version. The workflow bumps `tauri.conf.json` + `Cargo.toml` + `Cargo.lock`, commits, tags, and triggers the release pipeline (signs, notarizes the macOS bundle, drafts a GitHub Release, updates the Homebrew tap).
GitHub → Actions → **Cut Release** → enter the version. The workflow bumps `tauri.conf.json` + both `Cargo.toml`s + `Cargo.lock` + the README download URLs, commits, tags, and triggers the release pipeline (signs, notarizes the macOS bundle, drafts a GitHub Release, updates the Homebrew tap).
Loading
Loading