Skip to content

refactor(vault): resize VaultProvider to note-file operations - #123

Merged
AlexMost merged 4 commits into
mainfrom
worktree-consolidate-vault-writes-g2
Aug 31, 2026
Merged

AlexMost merged 4 commits into
mainfrom
worktree-consolidate-vault-writes-g2

Conversation

@AlexMost

Copy link
Copy Markdown
Owner

Refs #114 — group 2 of 3 for consolidate-vault-writes (PR 1 was #122).

VaultProvider sheds its two vault-wide aggregates and is left with the six
methods that each open exactly one note file over the vault root. listTags and
listProperties become free functions over a VaultReader in
src/lib/obsidian/vault-aggregates.ts — under src/lib/ because
computeVaultOverview is, and nothing under src/lib/ may import
src/modules/.

list_tags, list_properties, and get_vault_overview return identical
payloads. Only the call site moved. No schema, output shape, or error-code
change.

Commits

  1. derive tag and property aggregates from the reader — new
    vault-aggregates.ts; the provider delegates for now, so nothing outside the
    module changes.
  2. compute the vault snapshot from reader and graph alone —
    ComputeVaultOverviewDeps narrows to { reader, graph, readConventions },
    with both callers (the get_vault_overview tool and the vault://overview
    resource) updated in the same commit.
  3. resize VaultProvider to note-file operations — the type change, with
    every call site it breaks.

Payload parity is pinned, not assumed

headless-overview.test.ts gains a case asserting the full overview literal —
every field, in order — captured from the provider-backed
computeVaultOverview over that exact vault before the aggregates moved.

Two deviations from the plan's Group 2 text

The two fs-vault-provider disk suites are retargeted and moved, not
deleted.
The plan called them superseded by the new fake-reader suite. They
are not: between them they pin ~25 YAML- and disk-level cases a fake reader
cannot reach — scalar tags:, '#alpha' stripping, empty tags: [], broken
frontmatter, nested-object and array-valued properties, >32-note batching,
nested folders. They now live in test/lib/obsidian/ as
vault-aggregates-{tags,properties}-disk.test.ts, driving the free functions
over a real FsVaultReader, every case preserved verbatim. The new
vault-aggregates.test.ts covers aggregation semantics plus the reader-error
branch that disk tests cannot reach.

Scope exclusion needed no relocation. The plan said to move that case out of
fs-vault-provider/list-tags.test.ts into headless-overview.test.ts. It was
never there — it lives in vault-scope-e2e.test.ts, which already builds a real
scoped FsVaultReader. Those two cases retarget to the free functions in place.

Every retargeted assertion was checked case by case against what it asserted
before; the suite count is unchanged at 1371 because nothing was dropped.

Call sites the plan did not list

The typecheck gate found three further VaultProvider stubs beyond
test/operations/tools/_helpers.ts — in server-modules.test.ts,
operations-module.test.ts, and tools.test.ts — plus two inert as never
stubs in the prose suites. All resized in the same commit as the type change.

Dead-code sweep

src/modules/operations/types.ts carried OperationsToolHandlers, whose last
consumer went away in group 1. Removed, along with the seven *ToolInput types
that existed only to feed it (CreateNoteToolInput, EditNoteToolInput,
ReadNotesToolInput, ReadDailyToolInput, RemovePropertyToolInput,
ListTagsToolInput, ListPropertiesToolInput). SetPropertyToolInput,
ContentMode, and the ReadNotesResult* types stay — all still live.

Acceptance

  • grep -rn "function makeProvider" test/ → exactly two: the stub in
    test/operations/tools/_helpers.ts, the real-module builder in
    test/operations/fs-vault-provider/_helpers.ts.
  • grep -rn "implements VaultProvider" src/ → one, FsVaultProvider.
  • VaultProvider has six methods.
  • listTags / listProperties in src/ appear only in vault-aggregates.ts,
    vault-overview.ts, and the two list tools — none in vault-provider.ts or
    fs-vault-provider.ts.
  • npm test (1371 passed), npm run lint, npm run typecheck, npm run build
    all pass.

Group 3 (the ADR and the docs sweep) follows after review.

🤖 Generated with Claude Code

AlexMost and others added 4 commits August 31, 2026 13:02
Move sortCounts, READ_BATCH_SIZE, and the frontmatter scan out of
FsVaultProvider into src/lib/obsidian/vault-aggregates.ts as listTags(reader)
and listProperties(reader). The module lives under src/lib/ because
computeVaultOverview does, and nothing under src/lib/ may import src/modules/.

FsVaultProvider.listTags / listProperties delegate for now, so nothing outside
the module changes yet.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…alone

ComputeVaultOverviewDeps narrows to { reader, graph, readConventions } and
calls listTags/listProperties directly, so the overview no longer needs a
VaultProvider. Both callers — the get_vault_overview tool and the
vault://overview resource — stop passing entry.provider in the same commit.

The four overview suites now seed tags and properties through the reader
instead of stubbing provider aggregates. headless-overview.test.ts gains a
parity case pinning the full snapshot literal captured from the
provider-backed implementation over the same vault, field for field and order
for order.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Drop listTags / listProperties from the VaultProvider interface and from
FsVaultProvider, leaving the six methods that each open exactly one note file
over the vault root. The list_tags and list_properties tools now call the
vault-aggregates free functions with entry.reader.

Ships with every call site the type change breaks, in one commit: the
makeProvider stub in test/operations/tools/_helpers.ts plus the three further
VaultProvider stubs in server-modules, operations-module, and tools tests, and
the two inert `as never` provider stubs in the prose suites.

The two disk suites move to test/lib/obsidian/ and retarget to the free
functions rather than being deleted — they pin ~25 YAML- and disk-level cases
(scalar tags, '#alpha' stripping, empty tags: [], broken frontmatter,
nested-object and array properties, >32-note batching) that a fake reader
cannot reach. The scope-exclusion cases in vault-scope-e2e.test.ts retarget the
same way, keeping their real scoped FsVaultReader.

Also sweeps OperationsToolHandlers and the seven *ToolInput types that existed
only to feed it — dead since the tool builders took over.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@AlexMost
AlexMost merged commit d00f6cf into main Aug 31, 2026
2 checks passed
@AlexMost
AlexMost deleted the worktree-consolidate-vault-writes-g2 branch August 31, 2026 20:45
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