Skip to content

Vendor explicit file-focus navigation + viewed/collapse shortcuts#64

Open
dastratakos wants to merge 7 commits into
dastratakos/cli-shared-file-treefrom
dastratakos/cli-file-focus-nav
Open

Vendor explicit file-focus navigation + viewed/collapse shortcuts#64
dastratakos wants to merge 7 commits into
dastratakos/cli-shared-file-treefrom
dastratakos/cli-file-focus-nav

Conversation

@dastratakos
Copy link
Copy Markdown
Contributor

@dastratakos dastratakos commented Jun 2, 2026

Summary

Syncs the CLI with the monorepo's keyboard-navigation overhaul that landed after the fork. Replaces the CLI's scroll-derived "active file" model with an explicit focused-file state machine and adds the file-level keyboard shortcuts.

Stacked on #63 (shared file tree). Review/merge that first — this PR is based on dastratakos/cli-shared-file-tree, and its focusedFilePath wiring depends on the tree consumers introduced there. Rebases onto main once #63 lands.

Ports two monorepo PRs:

  • #943 — explicit file focus navigation. New useCurrentFile tracks currentFilePath + isFileKeyboardMode; a shared useFileDiffNavigation orchestrator owns the diff-viewer ref and wires every shortcut. Keyboard focus shows an outline ring (keyboardFocusedFilePath); click/scroll selection only highlights the picker row (currentFilePath).
  • #975 / #910v (mark file viewed + advance focus, pinning the marked file to the top), ; / Shift+; (collapse file / all files), Esc (exit keyboard mode), and re-bind chapter-viewed from vShift+V. file-header gains ShortcutTooltip hints on the viewed + collapse controls.

Changes

  • New hooks (vendored, imports adapted to @/lib/*): use-current-file, use-file-viewed-key, use-file-collapse-keys, use-file-keyboard-mode-exit-key, use-file-diff-navigation. use-file-navigation-keys rewritten to the focus signature (files, currentFilePath, onFocusFile, enabled).
  • Deleted: use-active-file-on-scroll.ts (the old scroll heuristic).
  • Registry: added MARK_FILE_AS_VIEWED, EXIT_FILE_KEYBOARD_MODE, TOGGLE_FILE_COLLAPSED, TOGGLE_ALL_FILES_COLLAPSED; re-bound MARK_CHAPTER_AS_VIEWED to Shift+V.
  • Routes: both files-page and chapter-detail-page delegate to useFileDiffNavigation; the chapter page's key-change focus now uses the orchestrator's scrollToLine/cancelScrollToLine. FileDiffList gains a focusedFilePath outline.
  • CLI simplification: the orchestrator's canToggleViewed gate stays at its default true — the CLI's viewed state is client-side and always writable (no server node-id gate).
  • Tests: ported the monorepo's file-focus-shortcuts test (16 cases).

Testing

  • pnpm typecheck
  • pnpm lint
  • pnpm test ✅ (web 105, incl. 16 new; the only red was pre-existing flaky-under-load timeouts in cli/git.test.ts, which pass 12/12 in isolation)
  • pnpm build

Open in Stage

Summary by cubic

Switches the CLI to explicit file focus navigation and adds file-level viewed/collapse shortcuts. Chapters auto-advance on completion; chapter navigation preserves scroll and realigns the next chapter’s first file under the header.

  • New Features

    • Explicit focus via useCurrentFile, with a “file keyboard mode” that outlines the focused diff.
    • Shared useFileDiffNavigation wires j/k, v, ;, Shift+;, Esc, and owns scroll-to-file/line for both files-page and chapter-detail-page.
    • v toggles file viewed and advances focus; Shift+V toggles chapter viewed and advances. Finishing a chapter’s last unviewed file auto-marks the chapter and advances.
    • file-header shows ShortcutTooltip and a collapse shortcut label; FileDiffList accepts focusedFilePath and outlines the active diff.
  • Bug Fixes

    • Preserve scroll between chapters and realign the next chapter’s first file under the header; key-change jumps select the target file so the picker and shortcuts stay in sync.
    • Align collapse-all with the hosted app; Files tab collapse defaults are scoped to the current diff so Shift+; reliably toggles all files.
    • Remove Files tab deep-link (scrollTo) and show Prologue focus locations as plain text, matching the hosted app.

Written for commit 7280c6d. Summary will update on new commits.

Review in cubic

…ortcuts

Syncs the CLI with the monorepo's keyboard-navigation overhaul that
landed after the fork:

- #943: replace scroll-derived "active file" with an explicit focused-file
  state machine (useCurrentFile) + a shared orchestrator (useFileDiffNavigation)
  that owns the diff-viewer ref and wires every file shortcut. Adds a
  "file keyboard mode" so keyboard focus shows an outline ring while
  click/scroll selection only highlights the picker row.
- #975: add v (mark file viewed + advance, pinning the marked file to top),
  ; / Shift+; (collapse file / all files), Esc (exit keyboard mode), and
  re-bind chapter-viewed from v to Shift+V (#910). file-header gains
  ShortcutTooltip hints on the viewed + collapse controls.

New hooks (vendored, imports adapted to @/lib/*): use-current-file,
use-file-viewed-key, use-file-collapse-keys, use-file-keyboard-mode-exit-key,
use-file-diff-navigation; use-file-navigation-keys rewritten to the focus
signature. The old scroll heuristic use-active-file-on-scroll is deleted.
Both routes now delegate to useFileDiffNavigation; FileDiffList gains a
focusedFilePath outline. Ported the monorepo's file-focus-shortcuts test
(16 cases).

CLI simplification: the canToggleViewed gate stays at its default (the CLI's
viewed state is client-side and always writable).

Typecheck, lint, web tests (105), and build all pass.
@stage-review
Copy link
Copy Markdown

stage-review Bot commented Jun 2, 2026

Ready to review this PR? Stage has broken it down into 6 individual chapters for you:

Title
1 Define new keyboard shortcut constants
2 Implement explicit file focus and navigation hooks
3 Update UI components for explicit focus
4 Integrate navigation into the Files page
5 Integrate navigation into Chapter Detail page
6 Refine scroll behavior and prologue links
Open in Stage

Chapters generated by Stage for commit 7280c6d on Jun 3, 2026 12:37am UTC.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 20c4ba6dfa

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/web/src/routes/files-page.tsx Outdated
Comment thread packages/web/src/routes/chapter-detail-page.tsx
Comment thread packages/web/src/lib/use-file-diff-navigation.ts
…ll files viewed

Mirrors the hosted app's chapter mark-complete flow (chapter-context.tsx
handleMarkComplete / toggleChapterFileViewed), which the CLI lacked:

- Marking a chapter viewed (Shift+V or the navigator toggle) now advances
  to the next chapter — or returns to the run's chapter list once every
  chapter is viewed.
- Marking a chapter's last unviewed file now auto-marks the chapter viewed
  and advances, so finishing a chapter by its files behaves like Shift+V.

Both routes through a shared advanceAfterChapterComplete helper. The all-
viewed/next-chapter check reads the pre-mark view-state snapshot (the
optimistic cache patch lands a tick later), matching the monorepo's
current-snapshot logic. Confetti is intentionally omitted (CLI has none).

Verified locally via stagereview show: completing a chapter's files marks
it viewed and navigates to the next chapter. typecheck, lint, test (315) pass.
Comment thread packages/web/src/routes/files-page.tsx Outdated
Comment thread packages/web/src/lib/use-file-diff-navigation.ts
The chapter detail page scrolls the window, and TanStack Router defaults
to resetScroll: true, so every chapter-to-chapter navigation jumped back
to the top. The hosted app passes resetScroll: false for on-detail-page
chapter nav (chapter-context.tsx navigateToPrev/Next/Chapter); the CLI's
navigations omitted it.

Add resetScroll={false} to the navigator's prev/next/jump <Link>s and to
the keyboard + auto-advance navigate() calls. Navigating to the run's
chapter list once all chapters are viewed keeps the default reset, matching
the hosted app's mark-complete-all flow.

Verified locally: scrolling down a chapter and advancing keeps the scroll
position instead of jumping to the top.
Comment thread packages/web/src/lib/use-file-diff-navigation.ts
resetScroll: false alone left the window at the prior chapter's offset, so
advancing could strand the reader deep in (or past) the next chapter. The
hosted app realigns the diff column to the new chapter's first file under
the sticky header on chapter change, gated on the side panel being pinned
(i.e. only when scrolled into the content).

Port that to the CLI's window-scroll model: a useLayoutEffect keyed on
chapter id scrolls to the first file when the carried-over offset left it
above --content-top, and leaves the view alone when already near the top
(so the chapter summary stays visible).

Verified locally: scrolled to the bottom of a chapter then advanced -> the
next chapter's first file snaps under the header; advancing from the top
leaves the view in place.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a299c5e1f6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/web/src/routes/chapter-detail-page.tsx
Comment thread packages/web/src/routes/chapter-detail-page.tsx
…ll test

Addresses PR review (Bugbot/codex):
- Deep-link scrollTo on the Files tab now selects the linked file (not just
  scrolls), so the picker highlights it and j/k/v/; start from it.
- Key-change jumps and the chapter-change first-file realign now select the
  file they scroll to, so shortcuts act on the file shown at the top instead
  of a stale path carried over from the previous chapter. This also makes the
  orchestrator's selectFile return value a live consumer (was unused).
- allCollapsed now tests membership (files.every(has)) instead of size >=
  length, so Shift+; can't flip to expand-all when collapsedFiles carries
  paths outside the current file list.

typecheck, lint, test (315) pass.
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 14 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread packages/web/src/lib/use-file-viewed-key.ts
…orepo

Match the hosted app rather than diverging:
- allCollapsed: revert to collapsedFiles.size >= files.length (the monorepo's
  test). Instead of a membership test, scope the Files-tab collapse defaults to
  the current files (only mark deleted/viewed paths that are in the diff), so
  collapsedFiles stays a subset of files exactly like the monorepo guarantees.
- Chapter-change realign now only scrolls to the first file (no selectFile),
  matching the monorepo's reset effect which repositions without touching
  file-focus state.

Key-change jumps still selectFile(target.filePath) — that DOES match the
monorepo (its chapter route effect selects the focused key change's file).

typecheck, lint, test (315) pass.
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 88059ac. Configure here.

Comment thread packages/web/src/routes/chapter-detail-page.tsx
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 3 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread packages/web/src/routes/chapter-detail-page.tsx
The hosted app has no scrollTo flow on the Files tab, so drop the CLI's:
- files route: remove the scrollTo search param + validateSearch schema
- FilesPage: remove the scrollTo prop and the select-on-scrollTo effect
- prologue Review Focus: the concern location is now plain text (matching
  pull-request-summary-section), not a link into the Files tab

PrologueSection no longer needs runId. typecheck, lint, test (315), build pass.
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 4 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/web/src/components/prologue/prologue-section.tsx">

<violation number="1" location="packages/web/src/components/prologue/prologue-section.tsx:83">
P1: Removed clickable file-location navigation from the prologue "Review Focus" section and replaced it with plain text. The previous `<Link>` navigated to `/runs/$runId/files?scrollTo=<location>`, letting users jump directly to the relevant file. The new `<span>` just displays the filename inertly — no navigation, no click target, no arrow affordance. This removes a user-facing path from a prologue focus-area item to its corresponding file in the diff view. The PR description discusses a new file-focus model but does not describe removing this prologue-to-file navigation, and no replacement navigation mechanism is introduced in this diff.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

>
{getFileName(area.locations[0])} &rarr;
</Link>
<span className="ml-auto shrink-0 text-xs text-muted-foreground">
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: Removed clickable file-location navigation from the prologue "Review Focus" section and replaced it with plain text. The previous <Link> navigated to /runs/$runId/files?scrollTo=<location>, letting users jump directly to the relevant file. The new <span> just displays the filename inertly — no navigation, no click target, no arrow affordance. This removes a user-facing path from a prologue focus-area item to its corresponding file in the diff view. The PR description discusses a new file-focus model but does not describe removing this prologue-to-file navigation, and no replacement navigation mechanism is introduced in this diff.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/web/src/components/prologue/prologue-section.tsx, line 83:

<comment>Removed clickable file-location navigation from the prologue "Review Focus" section and replaced it with plain text. The previous `<Link>` navigated to `/runs/$runId/files?scrollTo=<location>`, letting users jump directly to the relevant file. The new `<span>` just displays the filename inertly — no navigation, no click target, no arrow affordance. This removes a user-facing path from a prologue focus-area item to its corresponding file in the diff view. The PR description discusses a new file-focus model but does not describe removing this prologue-to-file navigation, and no replacement navigation mechanism is introduced in this diff.</comment>

<file context>
@@ -81,14 +80,9 @@ function PrologueDisplay({ prologue, runId }: { prologue: Prologue; runId: strin
-										>
-											{getFileName(area.locations[0])} &rarr;
-										</Link>
+										<span className="ml-auto shrink-0 text-xs text-muted-foreground">
+											{getFileName(area.locations[0])}
+										</span>
</file context>

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7280c6da60

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if (!el) return;
const contentTop = Number.parseFloat(getComputedStyle(el).getPropertyValue("--content-top"));
if (el.getBoundingClientRect().top < contentTop) {
diffListRef.current?.scrollToFile(firstPath);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Synchronize focus after chapter realignment

When moving between chapters with resetScroll: false, this branch scrolls the diff column to the new chapter's first file but leaves currentFilePath untouched; if the previously focused path also exists in the new chapter, useCurrentFile keeps that stale selection, so j/k/v/; operate on a different file than the one just pinned to the top. Fresh evidence since the earlier resolved thread is that the current diff removed the selectFile(firstPath) call after the scroll, reintroducing the stale-focus path.

Useful? React with 👍 / 👎.

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