fix: workspace watchers with Parcel watcher#1769
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughReplaces Changes
FFF Large-Workspace Timeout Fallback
Sequence Diagram(s)sequenceDiagram
participant WorkspacePresenter
participant FileWatcherService
participant WatcherPool
participant WatcherHostClient
participant UtilityProcess as FileWatcherHost (utility process)
participant Renderer as WorkspacePanel (renderer)
WorkspacePresenter->>FileWatcherService: watch(request, onBatch, onStatus)
FileWatcherService->>WatcherPool: watch(request, onBatch, onStatus)
WatcherPool->>WatcherHostClient: watch(request) via IPC RPC
WatcherHostClient->>UtilityProcess: fork + file-watcher:request watch
UtilityProcess-->>WatcherHostClient: file-watcher:status healthy/native
WatcherHostClient-->>WorkspacePresenter: onStatus(healthy)
WorkspacePresenter->>Renderer: sendToAllWindows workspace.watch.status.changed
UtilityProcess-->>WatcherHostClient: file-watcher:event-batch
WatcherHostClient-->>WatcherPool: onBatch(batch)
WatcherPool-->>WorkspacePresenter: filtered onBatch(batch)
WorkspacePresenter->>WorkspacePresenter: schedule invalidation (fs/git/full)
WorkspacePresenter->>Renderer: sendToAllWindows workspace.invalidated
UtilityProcess--xWatcherHostClient: unexpected exit
WatcherHostClient->>WatcherHostClient: handleHostExit → emitDegraded + scheduleRestart
WatcherHostClient-->>WorkspacePresenter: onStatus(degraded/utility-exit)
WorkspacePresenter->>Renderer: sendToAllWindows workspace.watch.status.changed (degraded)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Poem
✨ Finishing Touches🧪 Generate unit tests (beta)
|
There was a problem hiding this comment.
Actionable comments posted: 14
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
src/renderer/src/components/sidepanel/composables/useWorkspaceSync.ts (1)
421-427:⚠️ Potential issue | 🟠 Major | ⚡ Quick winRegister watch-status listeners before immediate watcher startup.
Line [397] runs
ensureWatcherState(...)immediately, but the new watch-status listener is attached at Line [425]. Earlyworkspace.watch.status.changedevents can be missed, so initial degraded/failed state may never surface in the panel.Suggested fix
-import { computed, onBeforeUnmount, onMounted, ref, watch, type ComputedRef, type Ref } from 'vue' +import { computed, onBeforeUnmount, ref, watch, type ComputedRef, type Ref } from 'vue' - onMounted(() => { - stopWorkspaceInvalidatedListener = options.workspaceClient.onInvalidated( - handleWorkspaceInvalidated - ) - stopWorkspaceWatchStatusListener = options.workspaceClient.onWatchStatusChanged( - handleWorkspaceWatchStatusChanged - ) - }) + stopWorkspaceInvalidatedListener = options.workspaceClient.onInvalidated( + handleWorkspaceInvalidated + ) + stopWorkspaceWatchStatusListener = options.workspaceClient.onWatchStatusChanged( + handleWorkspaceWatchStatusChanged + )🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/components/sidepanel/composables/useWorkspaceSync.ts` around lines 421 - 427, The watch-status listener registration is happening too late in the initialization sequence. In the onMounted hook in useWorkspaceSync.ts, the stopWorkspaceWatchStatusListener assignment (which registers the handler for workspace watch-status changes) needs to be moved to occur before the ensureWatcherState function is called, as ensureWatcherState triggers the watcher immediately and could emit status-change events before the listener is attached, causing initial degraded or failed states to be missed by the panel.src/renderer/src/i18n/es-ES/chat.json (1)
1-1:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winTranslate watchStatus strings into native languages.
All five non-English locale files contain English placeholder text for the new
workspace.files.watchStatuskeys instead of native-language translations:
src/renderer/src/i18n/es-ES/chat.json#L264-267: translate thedegradedandfailedstrings into Spanish.src/renderer/src/i18n/fa-IR/chat.json#L214-217: translate thedegradedandfailedstrings into Farsi/Persian.src/renderer/src/i18n/fr-FR/chat.json#L214-217: translate thedegradedandfailedstrings into French.src/renderer/src/i18n/he-IL/chat.json#L214-217: translate thedegradedandfailedstrings into Hebrew.src/renderer/src/i18n/id-ID/chat.json#L264-267: translate thedegradedandfailedstrings into Indonesian.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/renderer/src/i18n/es-ES/chat.json` at line 1, Replace the English placeholder text for the workspace.files.watchStatus keys in the five non-English locale files with native-language translations. In src/renderer/src/i18n/es-ES/chat.json (lines 264-267), translate the degraded and failed strings into Spanish. In src/renderer/src/i18n/fa-IR/chat.json (lines 214-217), translate the degraded and failed strings into Farsi/Persian. In src/renderer/src/i18n/fr-FR/chat.json (lines 214-217), translate the degraded and failed strings into French. In src/renderer/src/i18n/he-IL/chat.json (lines 214-217), translate the degraded and failed strings into Hebrew. In src/renderer/src/i18n/id-ID/chat.json (lines 264-267), translate the degraded and failed strings into Indonesian.Source: Coding guidelines
src/shared/types/presenters/workspace.d.ts (1)
97-102:⚠️ Potential issue | 🟠 Major | ⚡ Quick winKeep
WorkspaceInvalidationEvent.versionrequired to match the contract.Line 101 makes
versionoptional, butworkspace.invalidateddefinesversionas required. This weakens type safety across the shared event boundary.Suggested fix
export type WorkspaceInvalidationEvent = { workspacePath: string kind: WorkspaceInvalidationKind source: WorkspaceInvalidationSource - version?: number + version: number }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/shared/types/presenters/workspace.d.ts` around lines 97 - 102, The WorkspaceInvalidationEvent type marks the version field as optional with the ? modifier, but the workspace.invalidated contract requires version to be a non-optional required field. Remove the ? from the version property declaration in the WorkspaceInvalidationEvent type definition to make it a required field matching the actual contract requirement and restore type safety at the shared event boundary.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/issues/parcel-watcher-issue-1764/plan.md`:
- Around line 210-227: The fallback modes section documents
`git-metadata-polling` as a polling strategy, but this mode is missing from the
earlier `WatcherMode` union type definition and the status-event example that
shows the `mode` field values as `native | snapshot-polling | lifecycle`. To fix
this inconsistency, either add `git-metadata-polling` to the `WatcherMode` union
and update the status-event example to include `git-metadata-polling` as a valid
mode value, or remove `git-metadata-polling` from the Fallback modes section if
it is intended to be internal only. Whichever approach you choose, ensure that
the `WatcherMode` contract, the status-event example, and the documented
fallback modes all describe the same set of possible modes.
In `@docs/issues/parcel-watcher-issue-1764/spec.md`:
- Line 138: Remove the phrase "currently the latest npm release" from line 138
in the spec.md file. Keep only the part about the recommended dependency version
with the semantic versioning constraint "`@parcel/watcher`@^2.5.6". This
eliminates time-bound language that will become outdated when newer versions are
released, while maintaining the useful version specification information.
In `@docs/issues/parcel-watcher-issue-1764/tasks.md`:
- Around line 17-23: The verification checklist includes `pnpm run typecheck`
but the acceptance gate specification requires `pnpm run typecheck:node`. Update
the task list to use the correct command `pnpm run typecheck:node` that matches
the spec, or if both commands are required, add a note clarifying that both
should be executed by contributors.
In `@src/main/lib/fileWatcher/eventCoalescer.ts`:
- Around line 57-69: The code is using path.normalize on lines 59 and 66 to
normalize paths in the deletedParents array and when checking descendants, but
this is weaker than the normalizeEventKey normalization used elsewhere. Replace
both occurrences of path.normalize(event.path) in the deletedParents mapping and
the normalized variable assignment in the filter function with
normalizeEventKey(event.path) to ensure consistent and stronger path
normalization that prevents missing equivalent paths and leaking redundant
delete events.
In `@src/main/lib/fileWatcher/watcherHost.ts`:
- Around line 166-179: After detecting and reporting the terminal `root-deleted`
state in the root path existence check (where fs.existsSync fails for
activeWatch.request.rootPath), prevent any future polling from being scheduled
for this activeWatch. Identify the polling scheduling mechanism (likely a
timeout or interval setup) and ensure it is cancelled or prevented from being
re-scheduled once the `root-deleted` condition is detected and the status is set
to failed. This issue appears at two locations: the primary check at lines
166-179 and a secondary occurrence at lines 215-218; both sites need the same
fix to prevent polling from continuing after the terminal failure state is
reached.
In `@src/main/lib/fileWatcher/watcherHostClient.ts`:
- Around line 91-115: The request method does not have a timeout mechanism,
which means if the utility host becomes unresponsive and never replies, the
promise will hang indefinitely and leave entries in the pendingRequests Map
unresolved. Add a timeout to the promise created in the request method that
rejects after a reasonable duration (typically a few seconds). When the timeout
fires, delete the corresponding entry from pendingRequests using the id as the
key and reject the promise with an appropriate timeout error. This ensures that
hung RPC calls are cleaned up and do not block watch, unwatch, or shutdown
operations.
In `@src/main/lib/fileWatcher/watcherPool.ts`:
- Around line 108-130: When the watch promise in `entry.ready` rejects, the
entry remains in both the `entriesByKey` and `entriesByWatchId` maps, causing
future callers with the same key to inherit the failed promise and keep failing.
Add error handling around the `await entry.ready` statement to catch rejection
and clean up by removing the poisoned entry from both `entriesByKey` and
`entriesByWatchId` maps before re-throwing the error, allowing subsequent
requests with the same key to create a fresh entry and retry.
In `@src/main/lib/fileWatcher/watcherService.ts`:
- Around line 34-35: In the resetFileWatcherServiceForTests function, before
setting sharedWatcherService to null, you need to properly clean up the existing
watcher service instance to prevent watcher clients and processes from remaining
alive across tests. Add logic to check if sharedWatcherService exists and call
its cleanup method (such as destroy() or close()) before assigning null to
sharedWatcherService.
In `@src/main/presenter/skillPresenter/index.ts`:
- Around line 1955-1961: The code in this section calls discoverSkills() which
already publishes the skills.catalog.changed event internally, and then
immediately publishes the same event again at lines 1956-1960 with duplicate
data. Remove the redundant publishDeepchatEvent call for skills.catalog.changed
since the discoverSkills() method already handles this publication. Keep the
const skills assignment and the return statement.
In `@src/main/presenter/workspacePresenter/index.ts`:
- Around line 230-233: The fire-and-forget calls to
`this.refreshGitWatcher(runtime)` at lines 232 and 242 lack rejection handlers,
which can cause unhandled promise rejections. Add a `.catch()` handler to both
invocations of `refreshGitWatcher(runtime)` to properly handle any promise
rejections, ensuring errors are either logged or handled gracefully rather than
becoming unhandled rejections that could destabilize the runtime.
- Around line 168-176: The runtime is being added to the watchRuntimes map at
the beginning of the async setup sequence, before createContentWatcher and
refreshGitWatcher complete. If either of these async operations throws an error,
the runtime remains in the map but with incomplete or failed initialization,
causing subsequent watchWorkspace calls to find it in the map and only increment
refCount instead of retrying setup. Move the this.watchRuntimes.set(normalized,
runtime) call to execute only after both createContentWatcher and
refreshGitWatcher have completed successfully, ensuring the insertion is atomic
with the full initialization. This way, if setup fails at any point, the runtime
is not added to the map and can be properly retried on the next watchWorkspace
call.
In `@src/renderer/src/i18n/da-DK/chat.json`:
- Around line 214-217: The watchStatus object containing "degraded" and "failed"
messages remain in English across multiple non-English locale files. Replace the
English strings with proper translations in each file: in
src/renderer/src/i18n/da-DK/chat.json at lines 214-217 replace with Danish
translations, in src/renderer/src/i18n/de-DE/chat.json at lines 264-267 replace
with German translations, in src/renderer/src/i18n/pt-BR/chat.json at lines
214-217 replace with Brazilian Portuguese translations, in
src/renderer/src/i18n/ru-RU/chat.json at lines 214-217 replace with Russian
translations, and in src/renderer/src/i18n/tr-TR/chat.json at lines 264-267
replace with Turkish translations. For each file, translate both the
watchStatus.degraded and watchStatus.failed string values into the corresponding
target language.
In `@src/renderer/src/i18n/it-IT/chat.json`:
- Around line 264-267: The workspace watch-status strings contain English
placeholder text in five locale files instead of proper translations. Translate
both the degraded and failed keys under workspace.files.watchStatus to the
appropriate language at each location: in src/renderer/src/i18n/it-IT/chat.json
(lines 264-267) translate to Italian, in src/renderer/src/i18n/ja-JP/chat.json
(lines 214-217) translate to Japanese, in src/renderer/src/i18n/ko-KR/chat.json
(lines 214-217) translate to Korean, in src/renderer/src/i18n/ms-MY/chat.json
(lines 264-267) translate to Malay, and in src/renderer/src/i18n/pl-PL/chat.json
(lines 264-267) translate to Polish. For each locale, replace the English text
for both degraded ("Watching in fallback mode. Changes may refresh slower.") and
failed ("File watching is unavailable. Refresh or reselect the workspace.") with
their native language equivalents.
In `@src/renderer/src/i18n/vi-VN/chat.json`:
- Around line 264-266: The watchStatus strings (degraded and failed) in the
locale files are using placeholder text that was not properly localized for each
target language. In src/renderer/src/i18n/vi-VN/chat.json at lines 264-266,
replace the English watchStatus.degraded and watchStatus.failed messages with
Vietnamese-localized translations. In src/renderer/src/i18n/zh-HK/chat.json at
lines 222-224, replace the Simplified Chinese watchStatus text with proper
Traditional Chinese (Hong Kong) phrasing. In
src/renderer/src/i18n/zh-TW/chat.json at lines 222-224, replace the Simplified
Chinese watchStatus text with proper Traditional Chinese (Taiwan) phrasing.
Ensure each locale has culturally appropriate and grammatically correct
translations for both the degraded and failed status messages.
---
Outside diff comments:
In `@src/renderer/src/components/sidepanel/composables/useWorkspaceSync.ts`:
- Around line 421-427: The watch-status listener registration is happening too
late in the initialization sequence. In the onMounted hook in
useWorkspaceSync.ts, the stopWorkspaceWatchStatusListener assignment (which
registers the handler for workspace watch-status changes) needs to be moved to
occur before the ensureWatcherState function is called, as ensureWatcherState
triggers the watcher immediately and could emit status-change events before the
listener is attached, causing initial degraded or failed states to be missed by
the panel.
In `@src/renderer/src/i18n/es-ES/chat.json`:
- Line 1: Replace the English placeholder text for the
workspace.files.watchStatus keys in the five non-English locale files with
native-language translations. In src/renderer/src/i18n/es-ES/chat.json (lines
264-267), translate the degraded and failed strings into Spanish. In
src/renderer/src/i18n/fa-IR/chat.json (lines 214-217), translate the degraded
and failed strings into Farsi/Persian. In src/renderer/src/i18n/fr-FR/chat.json
(lines 214-217), translate the degraded and failed strings into French. In
src/renderer/src/i18n/he-IL/chat.json (lines 214-217), translate the degraded
and failed strings into Hebrew. In src/renderer/src/i18n/id-ID/chat.json (lines
264-267), translate the degraded and failed strings into Indonesian.
In `@src/shared/types/presenters/workspace.d.ts`:
- Around line 97-102: The WorkspaceInvalidationEvent type marks the version
field as optional with the ? modifier, but the workspace.invalidated contract
requires version to be a non-optional required field. Remove the ? from the
version property declaration in the WorkspaceInvalidationEvent type definition
to make it a required field matching the actual contract requirement and restore
type safety at the shared event boundary.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: dbc3bff8-cecf-4d26-b6b2-d1d43a7873f2
📒 Files selected for processing (56)
docs/issues/parcel-watcher-issue-1764/plan.mddocs/issues/parcel-watcher-issue-1764/spec.mddocs/issues/parcel-watcher-issue-1764/tasks.mdelectron-builder.ymlelectron.vite.config.tspackage.jsonscripts/afterPack.jssrc/main/fileWatcherUtilityHostEntry.tssrc/main/lib/fileWatcher/eventCoalescer.tssrc/main/lib/fileWatcher/fileWatcherUtilityHost.tssrc/main/lib/fileWatcher/index.tssrc/main/lib/fileWatcher/watcherHost.tssrc/main/lib/fileWatcher/watcherHostClient.tssrc/main/lib/fileWatcher/watcherPool.tssrc/main/lib/fileWatcher/watcherService.tssrc/main/lib/fileWatcher/watcherTypes.tssrc/main/presenter/index.tssrc/main/presenter/skillPresenter/index.tssrc/main/presenter/workspacePresenter/index.tssrc/renderer/api/WorkspaceClient.tssrc/renderer/src/components/sidepanel/WorkspacePanel.vuesrc/renderer/src/components/sidepanel/composables/useWorkspaceSync.tssrc/renderer/src/i18n/da-DK/chat.jsonsrc/renderer/src/i18n/de-DE/chat.jsonsrc/renderer/src/i18n/en-US/chat.jsonsrc/renderer/src/i18n/es-ES/chat.jsonsrc/renderer/src/i18n/fa-IR/chat.jsonsrc/renderer/src/i18n/fr-FR/chat.jsonsrc/renderer/src/i18n/he-IL/chat.jsonsrc/renderer/src/i18n/id-ID/chat.jsonsrc/renderer/src/i18n/it-IT/chat.jsonsrc/renderer/src/i18n/ja-JP/chat.jsonsrc/renderer/src/i18n/ko-KR/chat.jsonsrc/renderer/src/i18n/ms-MY/chat.jsonsrc/renderer/src/i18n/pl-PL/chat.jsonsrc/renderer/src/i18n/pt-BR/chat.jsonsrc/renderer/src/i18n/ru-RU/chat.jsonsrc/renderer/src/i18n/tr-TR/chat.jsonsrc/renderer/src/i18n/vi-VN/chat.jsonsrc/renderer/src/i18n/zh-CN/chat.jsonsrc/renderer/src/i18n/zh-HK/chat.jsonsrc/renderer/src/i18n/zh-TW/chat.jsonsrc/shared/contracts/domainSchemas.tssrc/shared/contracts/events.tssrc/shared/contracts/events/workspace.events.tssrc/shared/types/presenters/index.d.tssrc/shared/types/presenters/workspace.d.tssrc/shared/types/skill.tstest/e2e/specs/30-workspace-watcher-events.smoke.spec.tstest/main/lib/fileWatcher/eventCoalescer.test.tstest/main/lib/fileWatcher/watcherPool.test.tstest/main/presenter/skillPresenter/skillPresenter.test.tstest/main/presenter/workspacePresenter.test.tstest/main/routes/contracts.test.tstest/main/scripts/afterPack.test.tstest/renderer/components/WorkspacePanel.test.ts
| if (!fs.existsSync(activeWatch.request.rootPath)) { | ||
| this.enqueueEvents(activeWatch, [ | ||
| { | ||
| path: activeWatch.request.rootPath, | ||
| type: 'root-deleted' | ||
| } | ||
| ]) | ||
| this.sendStatus(activeWatch, { | ||
| health: 'failed', | ||
| mode: activeWatch.mode, | ||
| reason: 'root-deleted' | ||
| }) | ||
| return | ||
| } |
There was a problem hiding this comment.
Stop polling after terminal root-deleted state to avoid repeated failure churn.
When rootPath is missing, the host emits root-deleted/failed but keeps scheduling polling, which can repeatedly fire the same failure path every interval and retrigger downstream invalidation work.
Suggested fix
@@
- void poll()
- activeWatch.pollTimer = setInterval(() => {
+ activeWatch.pollTimer = setInterval(() => {
void poll()
}, SNAPSHOT_POLL_INTERVAL_MS)
+ void poll()
@@
if (!fs.existsSync(activeWatch.request.rootPath)) {
this.enqueueEvents(activeWatch, [
{
path: activeWatch.request.rootPath,
type: 'root-deleted'
}
])
this.sendStatus(activeWatch, {
health: 'failed',
mode: activeWatch.mode,
reason: 'root-deleted'
})
+ if (activeWatch.pollTimer) {
+ clearInterval(activeWatch.pollTimer)
+ activeWatch.pollTimer = null
+ }
return
}Also applies to: 215-218
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/main/lib/fileWatcher/watcherHost.ts` around lines 166 - 179, After
detecting and reporting the terminal `root-deleted` state in the root path
existence check (where fs.existsSync fails for activeWatch.request.rootPath),
prevent any future polling from being scheduled for this activeWatch. Identify
the polling scheduling mechanism (likely a timeout or interval setup) and ensure
it is cancelled or prevented from being re-scheduled once the `root-deleted`
condition is detected and the status is set to failed. This issue appears at two
locations: the primary check at lines 166-179 and a secondary occurrence at
lines 215-218; both sites need the same fix to prevent polling from continuing
after the terminal failure state is reached.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/main/presenter/workspacePresenter/fileSearcher.ts (1)
56-61: 💤 Low valueConsider using Node's
Direnttype directly.The
FilesystemEntrytype duplicates the shape of Node'sDirent. Using the built-in type fromfswould be more idiomatic and would automatically stay in sync with Node.js updates.Suggested change
+import type { Dirent } from 'fs' import fs from 'fs/promises' import path from 'path'Then at line 240:
- let entries: FilesystemEntry[] + let entries: Dirent[]And remove lines 56-61.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/main/presenter/workspacePresenter/fileSearcher.ts` around lines 56 - 61, The custom FilesystemEntry type definition duplicates the built-in Node.js Dirent type from the fs module. Remove the FilesystemEntry type definition and import Dirent from Node's fs module instead. Then replace all usages of FilesystemEntry throughout the file (including at line 240 mentioned in the comment) with the Dirent type to use Node's idiomatic type that will automatically stay in sync with Node.js updates.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@src/main/presenter/workspacePresenter/fileSearcher.ts`:
- Around line 56-61: The custom FilesystemEntry type definition duplicates the
built-in Node.js Dirent type from the fs module. Remove the FilesystemEntry type
definition and import Dirent from Node's fs module instead. Then replace all
usages of FilesystemEntry throughout the file (including at line 240 mentioned
in the comment) with the Dirent type to use Node's idiomatic type that will
automatically stay in sync with Node.js updates.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 8a9ecf96-9f1f-460f-9df6-646c7b65c67d
📒 Files selected for processing (3)
docs/issues/fff-large-workspace-timeout/spec.mdsrc/main/presenter/workspacePresenter/fileSearcher.tstest/main/presenter/workspacePresenter/fileSearcher.test.ts
✅ Files skipped from review due to trivial changes (1)
- docs/issues/fff-large-workspace-timeout/spec.md
Summary
Closes #1764.
@parcel/watcherservice.Technical Design
WatcherServiceis the feature-facing facade. Presenters subscribe throughWatchRequestobjects and do not import native watcher code.WatcherHostClientowns utility-process lifecycle, RPC correlation, restart status, and request replay.WatcherPooldeduplicates equivalent subscriptions, normalizes macOS/private/varpaths, applies include/exclude filters, and fans batches out to subscribers.watcherHostruns inside the utility process, owns@parcel/watchersubscriptions, coalesces regular content events, chunks large batches, and switches to snapshot polling when native watching fails or overflows.Validation
pnpm run formatpnpm run i18npnpm run lintpnpm run typecheckpnpm test(388 files passed, 3222 tests passed; existing skipped suites unchanged)pnpm run buildpnpm exec playwright test -c test/e2e/playwright.config.ts test/e2e/specs/30-workspace-watcher-events.smoke.spec.tsSummary by CodeRabbit
Release Notes