Repository navigation
fix(quickfiler): navigate expanded subfolders with arrow keys (#1007) - #1010
Merged
Merged
Conversation
…e bug folder Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014ASyXWyEc23fGahFNciw3P
Commit the confirmed grill-me transcript (rounds 1 to 3) for the EFC/QFC arrow-key subfolder navigation bug and record its eleven behaviour rules, plus the regression-test and toolchain gates, as acceptance criteria in issue.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019j43rEpkM36uCjKGmGSwWs
Add the task-researcher artifact for the EFC/QFC arrow-key subfolder navigation bug, record the maintainer's round 4 answers (Q23 to Q29) in the grill transcript, and amend the acceptance criteria in issue.md: AC5 drops the restore-full-path clause, AC8 to AC11 gain the round 4 clauses, and AC14 adds the invariant that no expand affordance is shown on a folder without subfolders, with the root cause in OutlookFolderHierarchyProvider.MapNode. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019j43rEpkM36uCjKGmGSwWs
Replace the spec template with the full-bug spec for issue #1007: root cause, design, message contracts, test strategy with failing tests first, test-disposition table for the removed #440 Left walk and the [+] restore, and AC1 to AC14 copied from issue.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019j43rEpkM36uCjKGmGSwWs
Add the 118-task atomic plan for the EFC/QFC arrow-key subfolder navigation bug, with failing regression tests first for each behaviour group, the spec amendments the planner made (selectorHighlight message, per-file coverage source, disposition-table rows), and the record of the four in-place preflight fixes. Preflight returned ALL CLEAR. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019j43rEpkM36uCjKGmGSwWs
- Move Up and Down through expanded subfolders in EFC and QFC viewers - Redefine Left, Right and Ctrl+Left; handle Home, End, PageUp, PageDown - Highlight the open subfolder in the QFC list - Change segment double-click; [+] lists that segment's subfolders - Hide [+] on folders without subfolders in MapNode - Guard against re-entrant Right while a fetch is in flight - Add regression tests and issue 1007 evidence Refs: #1007 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019j43rEpkM36uCjKGmGSwWs
Bring in #1005 (PR #1008, parallel test isolation) before the #1007 feature review. The two csproj files auto-merged without conflict. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019j43rEpkM36uCjKGmGSwWs
Add the policy audit, code review, feature audit and remediation inputs from the first review of #1007 (one blocking finding, B-1: the QFC pending highlight on a subfolder has no stylesheet rule), the reviewer's AC check-offs, and the post-merge toolchain evidence. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019j43rEpkM36uCjKGmGSwWs
- Apply the selected style to .sub.active in FolderBreadcrumb.html and add a string-contract test for the rule (review finding B-1) - Add four tests for router, coordinator and state-model paths that had lost direct coverage (N-1) - Rename six #440-era tests to match the current arrow-key behavior (N-2) - Check off AC4 again in issue.md and spec.md, and add the remediation plan and cycle 1 evidence Refs: #1007 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019j43rEpkM36uCjKGmGSwWs
Add the policy audit, code review and feature audit from the cycle 1 re-audit of #1007 (no blocking findings) and the human runbook for the manual Outlook keyboard verification. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019j43rEpkM36uCjKGmGSwWs
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.
Summary
spec.md(four grill-me rounds, confirmed on 2026-10-23). They cover Up and Down in tree order, no wrap at either end, select-on-move in EFC, the pending-highlight model in the open QFC list, standard tree Right and Left, Ctrl+Left parent selection, segment double-click, closed-list QFC behaviour, and Home, End, PageUp and PageDown.[+]could appear on a folder with no subfolders.OutlookFolderHierarchyProvider.MapNodenow derives has-children from the children that resolve in the folder snapshot.[+]restore of trailing segments.origin/main. Two feature reviews were run, and the re-audit passed. Manual Outlook verification is still pending.Why
The root cause analysis in
spec.mdrecords these causes:HandleUpArrowandMoveSelectioninQuickFiler/Controllers/BreadcrumbBridgeRouter.Arrows.csusedFindSelectableandIndexOf, which iterate_rowsonly. They never read the Bug: efc-qfc-folder-tree-selection-and-nesting #1002 descendant tree.SelectRowcalledTrySelectDescendant(null), so Down from a selected subfolder cleared it and jumped to the next row.BreadcrumbSelectionSession.Movetracked pending state by row identity only. QFC Left and Right went throughFolderBreadcrumbBridgeRouter.ArrowAsyncagainst the committed row, not the pending highlight. The page-sideonArrowpre-filter inFolderBreadcrumb.jsalso read the committed row.[+]without subfolders (AC14).MapNodesetHasChildrenfromnode.ChildKeys.Count > 0. A child key whose folder was absent from the snapshot therefore produced[+], a fetch returned zero children, and the expanded state showed[−]with nothing below it.ExpandLeafAsyncended with a toggle and had no guard. Two overlapping fetches (for example from key auto-repeat) each toggled, and the row ended collapsed.GetSelectedFolderignored the active segment; a single click on a segment in the open QFC list bubbled to the row commit; theReExpandrestore replaced the trailing segments instead of listing the active segment's children; and a collapse could leave the selection on a hidden node.What Changed
Shared visible-order helper (UtilitiesCS)
BreadcrumbVisibleOrderwith an immutableBreadcrumbVisiblePosition. It flattens rows and expanded descendants in pre-order and providesIndexOf,Step(clamped, no wrap),FirstandLast. Both viewers use it: EFC throughBreadcrumbRow.AppendVisiblePositions, and QFC throughBreadcrumbStateModel.VisiblePositions().EFC router and page script
QuickFiler/Controllers/BreadcrumbBridgeRouter.Navigation.cs. Moving onto a node commits throughSelectHierarchyPath(the mouse-click path, AC3). Moving onto a row entry goes through the newSelectRowEntry.ParentLeft(Ctrl+Left),Home,End,PageUpandPageDown. With nothing selected, Down and Home select the first row, and Up and End select the last.spec.md.TryRightTreeTransitionAsyncand the Bug: breadcrumb-left-right-arrow-parent-child-navigation #440 Left walk were removed.SegmentDoubleClickarm is now atomic: it activates the segment, commits it and shortens the row.BridgeJsinBreadcrumbDocumentAssets.csmaps the Ctrl and Home/End/Page keys and posts a measuredpageSize. It also scrolls to the selected.childwhen one is present.QFC selection session, router, coordinator and page script
BreadcrumbSelectionSession.Tree.cs. It addsPendingNode, the open-list visible-order walk, boundary and page moves, the Ctrl+Left parent move, and a row-shape snapshot thatCancelrestores (D-Q24).CommitPendingselects the pending descendant.FolderBreadcrumbBridgeRouter.Navigation.cs: when the list is open, Left and Right act on the pending entry.QuickFiler/Viewers/BreadcrumbBridgeCoordinator.Keyboard.cswith these rules:UnhandledArrow(Right), which opens the pop-out dialog.selectorSegmentDoubleClickmessage.BreadcrumbSelectionMap.SelectedRowValuemakesGetSelectedFolderreturn the folder the shortened row displays.BreadcrumbStateModel.LeftArrowandRightArrowlose the Bug: breadcrumb-left-right-arrow-parent-child-navigation #440 walks. A shortened row expands its active segment.BreadcrumbRenderProjectionemitsMinusat the shortened terminal while the row is expanded.FolderBreadcrumb.js:pageSize), and Ctrl+Left as theparentselector key.onArrowalways postsarrowKey, and C# decides the outcome (S6)..sub.active.FolderBreadcrumb.htmlgains the.sub.activestyle, so the pending subfolder highlight is visible. This was review finding B-1.AC14: no
[+]on a folder without subfoldersOutlookFolderHierarchyProvider.MapNodederivesHasChildrenfromsnapshot.GetChildren(node.Key).Count > 0.makeSubfoldersshow no expand or collapse affordance after a fetch that attached zero children.Re-entrancy guard
Tests
BreadcrumbVisibleOrderTestsBreadcrumbSelectionSessionTreeIssue1007TestsFolderBreadcrumbBridgeRouterIssue1007Tests(with anUnanchoredpartial)OutlookFolderHierarchyProviderIssue1007TestsBreadcrumbEmptyExpanderIssue1007TestsBreadcrumbBridgeJsKeysIssue1007TestsBreadcrumbBridgeRouterIssue1007Tests(withNavigationandDoubleClickpartials)BreadcrumbBridgeCoordinatorIssue1007Tests(with anUnhandledpartial)FolderBreadcrumbKeysIssue1007Teststests/quickfiler-breadcrumb/issue-1007-keys.test.mjs, plusgetBoundingClientRectstubs in the browser harness.[+]restore were rewritten or renamed. The reasons are recorded inevidence/other/test-renames.2026-10-25T23-59.md.Docs
docs/features/active/2026-10-22-efc-arrow-keys-skip-subfolders-1007/holds the issue, spec, research, plan, evidence, feature-review artifacts and the manual Outlook runbook.Architecture / How It Fits Together
BridgeJspostsarrowKey { rowId, key, pageSize? }.BreadcrumbMessageCodecdecodes it, andBreadcrumbBridgeRouterdispatches it to the Navigation partial.BreadcrumbVisibleOrder, locates the current position, steps, and commits throughSelectHierarchyPathorSelectRowEntry.FolderBreadcrumb.jspostsselectorKey { key, pageSize? }.BreadcrumbBridgeCoordinatorpasses it toBreadcrumbSelectionSession, which walks the visible order. Only the pending entry changes.selectorViewreturns to the page withpendingNodeIdentity, and the page highlights that subfolder.arrowKey. The Keyboard partial handles the open/closed and leaf cases and forwards the rest to the pending-aware Navigation partial ofFolderBreadcrumbBridgeRouter.SelectHierarchyPath. Ctrl+Left never selects the archive root.Verification
Completed
The final toolchain pass ran after the cycle 1 remediation. The branch already contained the
origin/mainmerge (8bdd970ee) at that point.dotnet tool run csharpier check .Checked 1700 filesmsbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:EnableNETAnalyzers=true /p:EnforceCodeStyleInBuild=truemsbuild TaskMaster.sln /t:Rebuild /m /p:Configuration=Debug "/p:Platform=Any CPU" /p:TreatWarningsAsErrors=truescripts/vscode/Invoke-MSTestWithCoverage.ps1tests/quickfiler-breadcrumbsuites, normal and reversed orderevidence/regression-testing/. These cover the visible order, EFC vertical, EFC horizontal, AC14, the QFC open and closed lists, QFC clicks, the page scripts, and the QFC pending style.e804f5d6bfixed it.Recommended
docs/features/active/2026-10-22-efc-arrow-keys-skip-subfolders-1007/runbooks/manual-outlook-keyboard-verification.runbook.md. It has not been run in this PR.node --test tests/quickfiler-breadcrumb/.Backward Compatibility / Migration Notes
Behaviour removed for keyboard users:
[+]restore of trailing segmentsParent selection is now Ctrl+Left.
The bridge-channel
segmentDoubleClickarm in the QFC router is now a logged no-op. QFC double-click moved to the selector channel (selectorSegmentDoubleClick).The message types gain optional constructor parameters with defaults (
pageSize,pendingNodeIdentity), so existing call sites compile unchanged.No settings, configuration or persisted-data changes. No migration is needed.
Risks and Mitigations
BreadcrumbBridgeJsKeysIssue1007Tests,FolderBreadcrumbKeysIssue1007Tests) pin the script contract inside the CI-run MSTest suite. CI has no node step.Review Guide
spec.md: the decision table for Right and Left, and AC1 to AC14.UtilitiesCS/OutlookObjects/Folder/BreadcrumbVisibleOrder.csand its tests.QuickFiler/Controllers/BreadcrumbBridgeRouter.Navigation.cs, then.Arrows.cs,.Selection.cs,.Descendants.cs, andBreadcrumbRow.BreadcrumbSelectionSession.Tree.cs,FolderBreadcrumbBridgeRouter.Navigation.cs,BreadcrumbBridgeCoordinator.Keyboard.cs,BreadcrumbStateModel, andBreadcrumbRenderProjection.OutlookFolderHierarchyProvider.MapNode, the renderer and projection protection, and their tests.BridgeJs,FolderBreadcrumb.js,FolderBreadcrumb.html, and the node suite.About 153 files changed. Most of the line count is feature-folder documentation and evidence under
docs/features/active/2026-10-22-efc-arrow-keys-skip-subfolders-1007/. Merge commit8bdd970eeonly brings inorigin/main.Follow-ups
GitHub Auto-close
🤖 Generated with Claude Code
https://claude.ai/code/session_019j43rEpkM36uCjKGmGSwWs