feat: manual reindex via HTTP, MCP, and settings UI#49
Merged
Conversation
The wiki index updates automatically on every write and on every sync
pull, but there was no way to force a fresh pass when files were
edited outside the API (directly on disk, sync edge case, etc.). Short
of restarting the server or waiting for the next sync tick — and the
sync tick only reindexes after a successful pull, so a non-sync wiki
had no recovery path at all.
Wire it up end to end:
wiki.Reindex(ctx) now returns (ReindexStats, error). Stats include
total/added/updated/removed/unchanged + elapsed (Duration and
elapsed_ms for JSON). All existing callers updated; the slog INFO
line at the end is preserved verbatim so log consumers don't break.
HTTP: POST /api/reindex returns the stats. Safe to call concurrently
with the sync loop — wiki.Reindex uses per-page locks, no global
lock.
MCP: new reindex_wiki tool. Same shape as the HTTP endpoint; returns
the stats JSON via textResult. SKILL.md adds a short section
explaining when to use it ('rarely; only after editing on disk
outside the API').
WebUI: new 'Index' section in the settings panel with a 'Reindex now'
button. Shows the last-run stats inline (total · +added / ~updated
/ -removed · elapsed) or any error. Refreshes the sidebar page list
after success so the user immediately sees any pages the reindex
surfaced.
sync.Reindexer interface signature follows wiki.Reindex. sync now
imports wiki for the stats type — they already lived in the same
binary; this just makes the dependency explicit.
Tests:
- httpapi: TestReindex (basic) and TestReindexDetectsDirectFilesystem-
Changes (writes a file directly to disk, confirms it's invisible
until reindex, then visible after). The second test is the whole
point of the feature.
- mcp: TestReindexWiki asserts the JSON-shaped response includes
elapsed_ms and the expected counts for the seeded fixtures.
README + SKILL.md updated with the new tool.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a way to force a reindex pass over the on-disk wiki without restarting the server. Exposed in three places — REST, MCP, and the settings UI — so humans and agents both have a recovery path when the index drifts from disk.
Why
The wiki index updates automatically on every
create_page/update_page/delete_page/move_pageand on every successful sync pull. That covers the common case. But if files get edited outside the wiki API — directly on disk, via a sync that produced files unusually, or as a result of a future bug — there was no way to force the index to catch up short of restarting the binary. And on a non-sync-configured wiki there was no automatic recovery at all, since the sync loop is the only thing that periodically callsReindexpost-startup.What
POST /api/reindex→ JSON stats{total, added, updated, removed, unchanged, elapsed_ms}. Safe to call concurrently with the sync loop;wiki.Reindexuses per-page locks (no global lock).reindex_wikitool with the same shape. SKILL.md gets a short section that tells agents to use it rarely — only when they've edited files outside the wiki API and a follow-uplist_pages/search_pagesdoesn't reflect it.104 pages · +2 / ~1 / −0 · 47 ms) or any error. Refreshes the sidebar page list after success.wiki.Reindex(ctx)now returns(ReindexStats, error). The existing slog INFO line at the end is preserved verbatim so log consumers don't break.sync.Reindexerinterface follows the new signature.Tests
httpapi.TestReindex— basic stats round-trip.httpapi.TestReindexDetectsDirectFilesystemChanges— writes a file directly to the wiki root, verifies it's invisible viaGET /api/pages/...(404) until reindex, then visible after. This is the whole point of the feature.mcp.TestReindexWiki— asserts the JSON-shaped response and the expected counts on the seeded fixtures.Verification
Inside the devcontainer:
go test ./...— greengo test -race ./...— race-cleango vet ./...— cleannpm run build(webui) — cleanDocs
SKILL.md— adds the tool to the frontmatter list and a "Forcing a Reindex" section that explicitly tells agents not to use it as a first resort.README.md— adds the tool to the MCP tools table.