Repository navigation
feat(explorer): show progress while indexing large folders #82
Description
Problem
Opening a folder with many files and deeply nested subdirectories can take a long time. The Explorer remains blank until its recursive scan finishes, so the extension can appear frozen.
Scope and outcome
Show an animated, indeterminate spinning progress indicator in the Explorer pane while a folder is being indexed. The status must be accessible, and scanning must yield enough for the browser to paint and process input. This issue retains eager full-tree indexing and existing file-fingerprint behavior; lazy directory expansion, pagination, and changes to fingerprint policy are out of scope.
Architecture decisions
- Transactional scan: Scan a selected or persisted directory handle into a local candidate index. Replace the live workspace handle, entries, files, fingerprints, and Git metadata only after the scan succeeds. Cancellation or a failed scan leaves the existing workspace usable and visible.
- Explicit lifecycle: Model
idle → scanning → ready | failed | cancelled; usefinallyto clear the loading state on every terminal path. - Precise start signal: Add an API boundary (for example, an
onScanStartcallback or separate handle-selection and scan operations) so the UI entersscanningafter a handle is available and immediately before indexing—not while the directory picker is open. Apply the same lifecycle toopenFolder()andopenFolderFromHandle(). - Race safety: While scanning, disable actions that mutate or consume the workspace index. Guard completion with a monotonic request ID so a stale scan cannot replace a newer workspace.
- Cooperative scan: Yield to a browser task boundary before the first batch and after a bounded number of entries. The precise batch size is an implementation detail, but it must preserve deterministic final entries and fingerprints.
Implementation plan
Task 1: Define transactional scan and lifecycle contract
Refactor folder-open and persisted-handle scan paths to construct a local candidate snapshot, expose the scan lifecycle, and commit it atomically only after success.
Acceptance criteria:
- User cancellation and scan failure leave the prior workspace data and handle intact.
- New-folder opening and persisted-session restore use the same lifecycle.
- A later scan request cannot be overwritten by an earlier scan completion.
Likely files: src/ui/filesystem.js, src/ui/session-persistence.mjs
Task 2: Add Explorer-pane progress UI
Render a dedicated loading row in the Explorer pane with an animated indeterminate spinner and aria-live status text such as Loading folder…. Show it only during scanning, remove it on every terminal state, and prevent workspace-dependent Explorer interactions during the scan.
Acceptance criteria:
- The spinner is visible and animated while indexing is in progress.
- Assistive technology receives a concise loading announcement without repeated noisy updates.
- The old Explorer tree remains visible until a replacement workspace has successfully scanned.
Likely files: src/ui/toolbar.js, src/ui/index.html, src/ui/styles.css
Task 3: Make scanning cooperative
Yield during recursive indexing so the loading row paints before scanning and stays animated during large scans, while preserving the final sorted entries, file handles, and fingerprints.
Acceptance criteria:
- The scan yields before the first batch and periodically thereafter.
- The completed snapshot matches existing contents and ordering semantics.
Likely files: src/ui/filesystem.js
Task 4: Prove lifecycle, responsiveness, and compatibility
Extend the fake directory-handle tests with delayed, nested entries and add browser-level or manual verification for visible paint and animation.
Acceptance criteria:
- Tests assert the loading lifecycle begins before scan resolution, ends on success, cancellation, and errors, and preserves the old workspace on non-success.
- Tests assert stale completions cannot win a scan race and the final tree includes all nested entries.
- Browser-level/manual verification confirms the animated spinner visibly paints during a deliberately slow scan.
Likely files: scripts/e2e-workspace-file-tracking.test.mjs, scripts/e2e-session-persistence.test.mjs, browser smoke-test support as needed.
Checkpoint
-
npm run lint -
npm run build -
npm run test:e2e - Manual check: open a large nested folder and confirm the animated Explorer spinner appears before the completed tree, remains animated while scanning, and clears when the tree is ready.
Risks and mitigations
| Risk | Mitigation |
|---|---|
| Loader does not paint before synchronous scan work | Yield to a browser task boundary immediately after setting scanning, then batch future yields. |
| A selected folder fails or is cancelled | Keep all live workspace state unchanged until atomic commit. |
| Overlapping opens cause stale data | Tie each scan to a request ID and ignore stale completion. |
| Large tree rendering is itself slow | This issue addresses indexing feedback; profile rendering separately if it remains a bottleneck. |
Activity
kbuffardi commentedon Sep 4, 2026
Decision record: the requester directed, "open a new issue" after reviewing the proposed Explorer-loading plan. This issue is the implementation source of truth; a future pull request should use a short-lived feature branch and include
Closes #82.kbuffardi commentedon Sep 4, 2026
Plan revision requested by @kbuffardi: "update the plan with these revisions. More precisely, also specify that the Explorer pane should indicate progress to the user via an animated spinning progress indicator. Update this spec and review it again"\n\nCodex updated the issue to require a transactional scan, explicit lifecycle, precise scan-start signal, cooperative yielding, request-ID race protection, and an animated, accessible Explorer-pane spinner. The revised plan has been re-reviewed and is ready for implementation.
kbuffardi commentedon Sep 4, 2026
Implementation is ready for review in PR #83, which includes the transactional scan, cooperative yielding, accessible animated Explorer spinner, and lifecycle regression coverage. The PR closes this issue when merged.