fix(web): find ignored files past the copy picker cutoff#24795

open3
main
fix/issue-24504
opened14d agobyJJulius Marminge
View on GitHubTwo-way sync enabledPR last imported 8d ago

Problem

In Add to another machine, a Git project with more than 200 eligible ignored files shows only the first 200. Files after the cutoff cannot be selected for copying. Reproduced on current main with 205 tracked-anchor folders and eligible ignored files through two normally paired isolated environments.

Change

Filter ignored paths by a bounded, case-insensitive search before applying the existing listing limit. Show the search field when the source supports it and the listing is truncated. Preserve selections and their sizes across searches, with All/None applying to shown results and a global 200-file selection limit.

The source capability keeps older servers on the existing picker. Per-file eligibility and copy behavior remain unchanged.

Scope and approval

Fixes https://github.com/pingdotgg/t3code/issues/24504

GitCafe: https://git.cafe/pingdotgg/t3code/issues/24504

Triaged bug via the automated issue flow. This fixes the existing ignored-file selection failure; no new copy capability or persisted state. The existing contributor #22844 remains untouched.

Verification

  • Regression test failed on main: searching for folder-205 returned only folders 001–200. It passes with this fix.
  • All 19 WorkspaceEntries tests pass. Contracts, server and web typechecks pass; changed-file lint and formatting pass.
  • Independent GPT-6.1-Sol and Claude Opus 5.5 diff reviews found no confirmed implementation bugs.
  • Two real paired servers: a filtered clone copied .env and candidates 204/205 with exact contents (3 files / 31 B). A second filtered clone copied exactly 200 ignored files / 1,607 B, including candidates beyond the cutoff. Unselected and oversize files were absent.
  • Runtime checks covered trimmed/case-insensitive queries, debounce, Enter not submitting, selection persistence, shown-only All/None, cap transitions, small/empty lists and size boundaries.

Evidence index · Complete bundle · Public fixture and driver

Rendering: Linux fs-15, built-in Browser panel, Node 26, separate isolated source/target homes. CSS 1440×900 transfers at 1280×800; CSS 390×844 captures at DPR 2. Light and dark themes. Before b3d382e100; captured after 203a30bacc. All 19 focused tests and contracts/server/web typechecks passed again after main merged cleanly into integrated head b703db7f13; rendering files are unchanged from the captured head. DiffT is luminance threshold 20; Diff0 masks expose changes, while the metric file's threshold-zero counts measure luminance rather than every RGB change.

FixtureBefore · b3d382e100After · 203a30baccDiff0DiffT20
Initial picker · 1440 · lightBefore 1440 lightAfter 1440 lightDiff0 1440 lightDiffT20 1440 light
Initial picker · 1440 · darkBefore 1440 darkAfter 1440 darkDiff0 1440 darkDiffT20 1440 dark
Initial picker · 390 · lightBefore 390 lightAfter 390 lightDiff0 390 lightDiffT20 390 light
Initial picker · 390 · darkBefore 390 darkAfter 390 darkDiff0 390 darkDiffT20 390 dark

Recordings: Search and three-file clone, selection cap and 200-file clone, query and Enter checks. Narrated steps, timestamps and destination transcripts are in the index.

Visible differences: search field, selection-summary and truncation wording, taller dialog and shifted content. Background timestamps, shadows and caret contribute comparison pixels; the captures do not claim that nothing else changed.

Unverified: actual older source binary (capability branches were synthetic), native desktop shell, hosted/remote-origin/relay/tunnel, exact-1-MiB destination copy. Responsive 390px evidence is web; native mobile has no picker caller. Loading/error checks in the initial bundle use synthetic UI state and do not prove real transport failures. The proof audit identifies missing interaction subcases; Supplemental recordings cover caller reset, whitespace-only query, partial-group and cap deselection, no-match/clear, legacy capability cap, and a real workspace-service failure. Supplemental audit resolves A, C, E, G and the synthetic I cap gap. H remains open: controlled initial/search pending states, fresh initial failure without cached defaults, and search-error clear restoring the original list. The H recording ends on the error, so recovery is not claimed as recorded proof. The I recording does not show the narrated repeat All; its initial exact-cap proof is sufficient. Hosted CI and bot review remain pending; no bugfix handoff label has been applied.

Models: GPT-6.1-Sol through the Codex harness; Claude Opus 5.5 through the Claude Agent harness.

Checks

22 successful · 6 skipped · 1 neutral
All checks passed
b703db7

Added 3 commits

  • fix: search ignored files past the listing limit when adding to another machine203a30b
  • test(server): ignored files past the listing limit can be found3365e44
  • Merge main into fix/issue-24504b703db7
Synced from GitHub

Approvability

Verdict: Needs Human Approval

Macroscope's review found this PR requires human approval — This PR adds ignored-file search and selection persistence to the clone picker, with the server capability enabled by default for standard environments. Because that default activates new user-facing behavior, the change warrants human review.

You can add or adjust custom eligibility rules. Learn more.

Synced from GitHub

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire5.0 KiB5.0 KiB0 B (0.0%)6.8 KiB✅
CodexThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiB✅
CodexLive turn WebSocket wire1.2 KiB1.2 KiB0 B (0.0%)2.0 KiB✅
CodexLive turn WebSocket decoded20.9 KiB20.9 KiB0 B (0.0%)29.3 KiB✅
CodexLive turn messages220 (0.0%)8✅
ClaudeTotal thread wire5.0 KiB5.0 KiB0 B (0.0%)6.8 KiB✅
ClaudeThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiB✅
ClaudeLive turn WebSocket wire1.2 KiB1.2 KiB0 B (0.0%)2.0 KiB✅
ClaudeLive turn WebSocket decoded21.2 KiB21.2 KiB0 B (0.0%)29.3 KiB✅
ClaudeLive turn messages220 (0.0%)8✅

Baseline: a96cf08 · PR result: b703db7 · Source CI: success

Scenario and decoded snapshot size

10 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.

  • Codex decoded thread snapshot: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

Synced from GitHub

Review in Change Stack →

No actionable comments were generated in the recent review.

External image Recent review info
External image Run configuration
External image Commits

Reviewing files that changed from the base of the PR and between a96cf0818eff4a113c3ff52ae702683e51a5803b and b703db7f13eafaf3dd561a69084c819d73cd59af.

External image Files selected for processing: 7
  • apps/server/src/environment/ServerEnvironment.ts
  • apps/server/src/workspace/WorkspaceEntries.test.ts
  • apps/server/src/workspace/WorkspaceEntries.ts
  • apps/web/src/components/AddProjectToMachineDialog.tsx
  • apps/web/src/lib/addProjectToMachine.ts
  • packages/contracts/src/environment.ts
  • packages/contracts/src/project.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 5 remain after this review.

Walkthrough

The server now supports case-insensitive ignored-file search before its listing limit. The machine-copy dialog uses that capability to search ignored files, retain selections across results, and cap selections at 200 files.

Changes: Ignored-file search and selection

Layer / File(s)Summary
Query contract and server filtering
packages/contracts/src/project.ts, packages/contracts/src/environment.ts, apps/server/src/environment/ServerEnvironment.ts, apps/server/src/workspace/WorkspaceEntries.ts, apps/server/src/workspace/WorkspaceEntries.test.ts
The request accepts an optional query of up to 256 characters. The server advertises search support and filters paths by query before applying its listing limit. A regression test checks that a match beyond 200 candidates is returned without truncation.
Dialog search and selection state
apps/web/src/lib/addProjectToMachine.ts, apps/web/src/components/AddProjectToMachineDialog.tsx
The dialog debounces supported searches and stores selected file records by path. Default selections come from the full listing.
Selection limits and clone submission
apps/web/src/components/AddProjectToMachineDialog.tsx
Selection is capped at 200 files. The dialog updates selections from shown rows, displays counts and search states, disables over-limit rows, and submits selected paths.

Priority: External image Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix · Severity of issue fixed: Medium

Sequence Diagram(s)

mermaid
1sequenceDiagram
2 participant User
3 participant AddProjectToMachineDialog
4 participant projects.listIgnoredFiles
5 participant WorkspaceEntries
6 User->>AddProjectToMachineDialog: Enter search query
7 AddProjectToMachineDialog->>projects.listIgnoredFiles: Request ignored files with query
8 projects.listIgnoredFiles->>WorkspaceEntries: Call listIgnoredFiles(query)
9 WorkspaceEntries-->>projects.listIgnoredFiles: Return filtered files
10 projects.listIgnoredFiles-->>AddProjectToMachineDialog: Return search results

Possibly related PRs

Suggested reviewers: t3dotgg

Merge Risk: External image Minimal · up to b703d

The change appears mergeable after normal checks; no actionable risk is established by the supplied evidence.

Pre-merge checks: Passed 4
Check nameStatusExplanation
Title checkPassedThe title clearly and concisely describes the main fix: finding ignored files beyond the copy picker’s 200-file cutoff.
Description checkPassedThe description includes all required sections. It explains the problem, implementation, scope and approval, verification results, UI evidence, limitations, and agent details.
Linked Issues checkPassedIssue #24504 requires access to eligible ignored files beyond the first 200 while keeping the 200-file selection limit, the 1 MiB per-file limit, and whole-ignored-folder exclusion. `WorkspaceEntries.…
Out of Scope Changes checkPassedThe changed files implement issue #24504. The contract and capability fields support compatibility with older servers. The server test covers the regression. The dialog changes implement search, selec…
Full details: Linked Issues check

Explanation

Issue #24504 requires access to eligible ignored files beyond the first 200 while keeping the 200-file selection limit, the 1 MiB per-file limit, and whole-ignored-folder exclusion. WorkspaceEntries.listIgnoredFiles applies the case-insensitive query before the 200-file cap and still excludes directory entries. The web dialog advertises and uses the search capability, preserves selections across results, limits selection to 200, and keeps oversized files disabled. The added regression test covers a file past the cutoff. The reported focused tests and typechecks also pass.

Full details: Out of Scope Changes check

Explanation

The changed files implement issue #24504. The contract and capability fields support compatibility with older servers. The server test covers the regression. The dialog changes implement search, selection persistence, bulk actions, and the existing copy limits. No unrelated product behavior or new copy capability is shown in the diff.

Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.