Repository navigation
feat(files): publish entry changes made outside the app - #8
Merged
Merged
Conversation
The Files tree only learned about changes the app itself made. The index
already picks up external creates and deletes through its own filesystem
watcher within ~100ms, but it exposes no change callback, so the server
never published the signal the client is already listening for.
A subscribed workspace now polls the one thing that is cheap to read -
the index entry count, `mixedSearch("", { pageSize: 1 }).totalMatched`,
about 0.5ms - once a second, and publishes the existing coarse signal
when it moves. One fibre per workspace root, refcounted to the
subscriptions, so the last unsubscribe stops it; no new filesystem
watcher, no rescan, no second channel. A read that fails is retried
after 30 seconds rather than leaving the workspace unwatched.
This narrows the gap rather than closing it: a rename, or a balanced
add and delete inside one interval, leaves the count where it was and
still waits out the client's 30s staleness window. Content-only edits
publish nothing by design - the tree does not render contents, and open
files have their own subscription.
Closes #4
Model: Claude Opus 5, harness: Claude Code
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: unavailable · PR result: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
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.
The Files tree only learned about changes the app itself made. A
touchin aterminal, a file added in Finder, or a build writing output stayed invisible
until the panel remounted or its 30s staleness window lapsed. The server-side
data was already live — the index picks up external creates and deletes through
its own filesystem watcher in ~100ms — but
FileFinderexposes no changecallback, so the server never learned the index had moved and #1's signal was
never published.
A subscribed workspace now polls the one thing that is cheap to read: the index
entry count,
mixedSearch("", { pageSize: 1 }).totalMatched, about 0.5msagainst this repo's 17k entries. When it moves, the existing coarse signal goes
out on the channel #1 built. One fibre per normalised workspace root, refcounted
to the subscriptions through an
RcMap, so the last unsubscribe stops it. Nonew filesystem watcher, no rescan, no second channel, and no contract, auth, or
client change. A read that fails logs a warning and is retried 30s later rather
than leaving the workspace unwatched for the rest of the subscription.
This narrows the gap rather than closing it. A rename, or a balanced add and
delete inside one interval, leaves the count where it was and publishes nothing;
those still wait out the client's 30s window, and in-app renames still go
through
refresh. Content-only edits publish nothing by design — the tree doesnot render contents, and
subscribeProjectFileChangesalready covers openfiles.
Verification
Focused tests (
vp test run apps/server/src/workspace/, 72 passed), lint, andtsgofort3,contracts, andclient-runtime. The two newWorkspaceEntriestests drive aTestClock, so they assert the silence and thesignal without a sleep or a timeout; both were mutation-checked — removing the
RcMap.getor the retry fails the matching test.Verified in the web client against a real index, with the Files panel open on
one tab and never remounted, counting the entry-change pushes on the socket:
touchappears in the tree, externalrmremoves it — one push eachnode_modules/, a 200KB cache blob, 5 commits and agit gc: zero pushestouchafter those quiet windows pushed exactly one, provingthe instrumentation was live throughout
No before/after images: nothing about the panel's appearance changes, only when
it stops being stale.
Closes #4
Model: Claude Opus 5, harness: Claude Code