Skip to content

feat: manual reindex via HTTP, MCP, and settings UI#49

Merged
aniongithub merged 1 commit into
mainfrom
fix/manual-reindex
May 24, 2026
Merged

feat: manual reindex via HTTP, MCP, and settings UI#49
aniongithub merged 1 commit into
mainfrom
fix/manual-reindex

Conversation

@aniongithub
Copy link
Copy Markdown
Owner

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_page and 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 calls Reindex post-startup.

What

  • HTTP: POST /api/reindex → JSON stats {total, added, updated, removed, unchanged, elapsed_ms}. Safe to call concurrently with the sync loop; wiki.Reindex uses per-page locks (no global lock).
  • MCP: new reindex_wiki tool 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-up list_pages / search_pages doesn't reflect it.
  • WebUI: new Index section in the settings panel with a "Reindex now" button. Shows the last-run stats inline (104 pages · +2 / ~1 / −0 · 47 ms) or any error. Refreshes the sidebar page list after success.
  • Engine: 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.Reindexer interface 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 via GET /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 ./... — green
  • go test -race ./... — race-clean
  • go vet ./... — clean
  • npm run build (webui) — clean

Docs

  • 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.

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.
@aniongithub aniongithub merged commit ceb7f47 into main May 24, 2026
1 check passed
@aniongithub aniongithub deleted the fix/manual-reindex branch May 24, 2026 01:09
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