Skip to content

feat(website): add file selection checkboxes for selective re-packing#791

Merged
yamadashy merged 20 commits intoyamadashy:mainfrom
spandan-kumar:feat/website-file-selection-checkboxes
Aug 24, 2025
Merged

feat(website): add file selection checkboxes for selective re-packing#791
yamadashy merged 20 commits intoyamadashy:mainfrom
spandan-kumar:feat/website-file-selection-checkboxes

Conversation

@spandan-kumar
Copy link
Contributor

feat: add file selection checkboxes for website UI

Implements the requested checklist feature for including/excluding files from GitHub repositories on the website UI.

Closes #754

Overview

This PR adds a comprehensive file selection interface to the Repomix website, allowing users to selectively choose which files to include in their packed output after the initial repository processing.

Features Implemented

Backend Enhancements

  • Extended API response to include complete file metadata (allFiles array)
  • Added FileInfo interface with path, token count, character count, and selection state
  • Modified PackResult to support file-level information for UI interaction

Frontend Components

  • New TryItFileSelection.vue component with interactive file list
  • Individual checkboxes for each file with path and statistics
  • Bulk selection controls: "Select All" and "Deselect All" buttons
  • Re-pack functionality: "Re-pack Selected" button to generate new output
  • Live statistics bar showing selected files count and token percentage

User Experience

  • Responsive design that works seamlessly on mobile and desktop
  • Scrollable file list for repositories with many files
  • Real-time updates of selection statistics as users check/uncheck files
  • Visual feedback with highlighted selected files
  • Seamless integration with existing website workflow

How It Works

  1. Initial Pack: User packs a repository using existing functionality
  2. File Selection UI: New section appears below results showing all processed files
  3. Interactive Selection: Users can check/uncheck individual files or use bulk actions
  4. Live Preview: Statistics update in real-time showing impact of file selection
  5. Re-pack: Click "Re-pack Selected" to generate new output containing only chosen files
  6. Preserved State: File selection is maintained across re-packing operations

UI Preview

image

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 19, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

Introduces a file selection UI and repack flow. Adds FileInfo/allFiles types to client/server, emits a repack event from TryItResult, handles it in TryIt.vue via a new repackWithSelectedFiles composable function, and updates server to return allFiles and token counts. Adjusts client API base URL env logic and tsconfig includes.

Changes

Cohort / File(s) Summary
Repack flow wiring (UI + composable)
website/client/components/Home/TryIt.vue, website/client/components/Home/TryItResult.vue, website/client/components/Home/TryItFileSelection.vue, website/client/composables/usePackRequest.ts
Adds file-selection UI component; TryItResult renders it and emits repack(files: FileInfo[]); TryIt.vue handles repack by calling new repackWithSelectedFiles; composable builds includePatterns and triggers repack, updating result/selection.
Client API types
website/client/components/api/client.ts
Adds FileInfo interface; extends PackResult.metadata with allFiles? and topFiles[].tokenCount; switches API_BASE_URL environment detection to use DEV.
Server result shaping
website/server/src/remoteRepo.ts, website/server/src/types.ts
Extends PackResult.metadata with allFiles entries (path, charCount, tokenCount, selected); adds tokenCount to topFiles; adds totalTokens to PackSummary; introduces server-side FileInfo type.
TypeScript config
website/client/tsconfig.json
Expands TS include patterns to components/composables/utils/constants.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant TFS as TryItFileSelection.vue
  participant TR as TryItResult.vue
  participant TV as TryIt.vue
  participant CPR as usePackRequest()
  participant S as Server (remoteRepo)

  U->>TFS: Select files + click "Re-pack Selected"
  TFS-->>TR: emit repack(selectedFiles)
  TR-->>TV: emit repack(selectedFiles)
  TV->>CPR: repackWithSelectedFiles(selectedFiles)
  activate CPR
  CPR->>S: handlePackRequest({ includePatterns from selected paths, ignorePatterns cleared })
  activate S
  S-->>CPR: PackResult { metadata: allFiles, topFiles, ... }
  deactivate S
  CPR-->>TV: updated result (mark selected)
  deactivate CPR
  TV-->>TR: pass updated result
  TR-->>TFS: render with new allFiles/selection
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Assessment against linked issues

Objective Addressed Explanation
UI checklist to include/exclude files in website (#754)
Repack using selected files from checklist (#754)

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
Switch API base URL env logic to use DEV for targeting (website/client/components/api/client.ts) Environment configuration change not required for file selection/repack checklist objective.
Add totalTokens to PackSummary (website/server/src/types.ts) Not referenced by the new checklist/repack UI; unrelated to stated objective.

Possibly related PRs

Suggested reviewers

  • yamadashy
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

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

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Summary of Changes

Hello @spandan-kumar, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a significant new feature to the Repomix website, enabling users to precisely control the content of their packed repository output. After an initial repository processing, users can now interactively select or deselect individual files via a new UI, and then re-pack the repository to generate output containing only the chosen files. This enhances customization and provides greater flexibility in managing packed code.

Highlights

  • Interactive File Selection UI: A new TryItFileSelection.vue component provides a user-friendly interface to view all processed files, complete with checkboxes for individual selection, bulk select/deselect options, and real-time statistics on selected files and token counts.
  • Dynamic Re-packing Functionality: Users can now trigger a "Re-pack Selected" action, which sends only the paths of the chosen files to the backend, allowing for on-demand regeneration of the packed output based on the refined selection.
  • Extended API and Data Models: The backend API response (PackResult) has been enhanced to include comprehensive metadata for all processed files (allFiles array), leveraging a new FileInfo interface that tracks file path, character count, token count, and selection state.
  • Improved Loading State: The loading indicator for repository processing has been updated for better user experience.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a great new feature allowing users to select specific files for re-packing. The implementation is comprehensive, touching both frontend and backend. The new Vue components are well-structured. I've identified a critical bug in how props are passed to the error component, which will prevent error messages from displaying correctly. I've also noted some opportunities for improvement regarding Vue best practices, such as avoiding direct prop mutation, and some minor fixes for robustness and consistency. Overall, a solid feature addition with a few areas to refine.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (14)
website/client/tsconfig.json (1)

19-29: Include declaration files for new directories (optional).

The expanded include globs look correct. To ensure ambient types and module augmentations in those folders are picked up, consider including .d.ts files as well.

   "include": [
     ".vitepress/**/*.ts", 
     ".vitepress/**/*.d.ts", 
     ".vitepress/**/*.tsx", 
     ".vitepress/**/*.vue",
     "components/**/*.ts",
     "components/**/*.vue",
+    "components/**/*.d.ts",
     "composables/**/*.ts",
+    "composables/**/*.d.ts",
     "utils/**/*.ts",
+    "utils/**/*.d.ts",
     "constants/**/*.ts"
+    ,"constants/**/*.d.ts"
   ],
website/server/src/types.ts (1)

19-24: Type shape for FileInfo matches client; consider exporting for reuse.

The server-side FileInfo mirrors the client shape well. Exporting it (and/or unifying overlapping fields with TopFile) can reduce drift between types over time.

-interface FileInfo {
+export interface FileInfo {
   path: string;
   charCount: number;
   tokenCount: number;
   selected?: boolean;
 }

Optional DRY improvement:

 interface TopFile {
-  path: string;
-  charCount: number;
-  tokenCount: number;
+  path: string;
+  charCount: number;
+  tokenCount: number;
 }
 
-interface FileInfo {
-  path: string;
-  charCount: number;
-  tokenCount: number;
-  selected?: boolean;
-}
+export interface FileInfo extends TopFile {
+  selected?: boolean;
+}
website/client/components/Home/TryIt.vue (1)

199-201: Make handleRepack async and await the composable (optional).

Awaiting the async composable here enables local try/catch or UI-side debouncing if needed and avoids overlapping calls.

-function handleRepack(selectedFiles: FileInfo[]) {
-  repackWithSelectedFiles(selectedFiles);
-}
+async function handleRepack(selectedFiles: FileInfo[]) {
+  await repackWithSelectedFiles(selectedFiles);
+}
website/server/src/remoteRepo.ts (1)

106-114: Coerce to numbers and consider response size for allFiles.

  • Prefer Number(...) to ensure numeric JSON values.
  • Exposing all files for large repos can bloat responses and cache entries. Consider capping, paging, or deferring details behind an additional endpoint/flag if you notice size/perf issues.
-        allFiles: Object.entries(packResult.fileCharCounts)
-          .map(([path, charCount]) => ({
-            path,
-            charCount: charCount as number,
-            tokenCount: packResult.fileTokenCounts[path] || 0,
-            selected: true, // Default to selected for initial packing
-          }))
+        allFiles: Object.entries(packResult.fileCharCounts)
+          .map(([path, charCount]) => ({
+            path,
+            charCount: Number(charCount),
+            tokenCount: Number(packResult.fileTokenCounts[path] ?? 0),
+            selected: true, // Default to selected for initial packing
+          }))
           .sort((a, b) => b.charCount - a.charCount),

If you decide to cap:

  • Add a server-side limit (e.g., first 10k entries) and include a truncated flag in metadata.
  • Or, provide a separate route to fetch allFiles with pagination.
website/client/composables/usePackRequest.ts (4)

102-104: Early-return on empty selection is fine; consider UX feedback (optional).

If the UI ever triggers repack with zero selections, setting a friendly error (or toasting) would be clearer than noop.

-  async function repackWithSelectedFiles(selectedFiles: FileInfo[]) {
-    if (!result.value || selectedFiles.length === 0) return;
+  async function repackWithSelectedFiles(selectedFiles: FileInfo[]) {
+    if (!result.value) return;
+    if (selectedFiles.length === 0) {
+      // Optional: provide UX feedback
+      // error.value = 'Select at least one file to re-pack.';
+      return;
+    }

115-117: Edge case: file paths containing commas.

Joining by comma mirrors the existing includePatterns semantics, but paths with commas will be ambiguous. If Repomix supports alternative separators or array payloads, consider that in the future.


131-153: Optimize selection marking from O(n²) to O(n).

Use a Set for membership checks when marking selected files in the response.

-          onSuccess: (response) => {
-            // Update file selection state in the new result
-            if (response.metadata?.allFiles) {
-              response.metadata.allFiles.forEach(file => {
-                file.selected = selectedPaths.includes(file.path);
-              });
-            }
-            result.value = response;
-          },
+          onSuccess: (response) => {
+            // Update file selection state in the new result
+            if (response.metadata?.allFiles) {
+              const selectedSet = new Set(selectedPaths);
+              response.metadata.allFiles.forEach((file) => {
+                file.selected = selectedSet.has(file.path);
+              });
+            }
+            result.value = response;
+          },

149-151: Pass file only when needed (optional).

For URL-based repacks, file is unused. Passing it conditionally can make intent clearer.

-          file: mode.value === 'file' || mode.value === 'folder' ? uploadedFile.value || undefined : undefined,
+          file:
+            mode.value === 'file' || mode.value === 'folder'
+              ? uploadedFile.value || undefined
+              : undefined,

(Functional no-op; purely readability.)

website/client/components/api/client.ts (2)

59-59: Allow overriding API base URL via env for preview/staging builds

Relying solely on import.meta.env.DEV can make preview deployments target production API unintentionally. Add an explicit VITE_API_BASE_URL override.

Apply this diff:

-const API_BASE_URL = import.meta.env.DEV ? 'http://localhost:8080' : 'https://api.repomix.com';
+const API_BASE_URL =
+  (import.meta.env.VITE_API_BASE_URL as string | undefined) ??
+  (import.meta.env.DEV ? 'http://localhost:8080' : 'https://api.repomix.com');

61-85: Harden error handling for non-JSON or network failures

If the server returns non-JSON on error (e.g., HTML error page) response.json() will throw before you surface an ApiError. Consider parsing the response as text first, then conditionally JSON-parse for robust errors, and wrap fetch in try/catch for network failures.

You can refactor packRepository like this (outside the selected lines):

export async function packRepository(request: PackRequest): Promise<PackResult> {
  const formData = new FormData();

  if (request.file) {
    formData.append('file', request.file);
  } else {
    formData.append('url', request.url);
  }
  formData.append('format', request.format);
  formData.append('options', JSON.stringify(request.options));

  let response: Response;
  try {
    response = await fetch(`${API_BASE_URL}/api/pack`, {
      method: 'POST',
      body: formData,
      signal: request.signal,
      headers: {
        Accept: 'application/json',
      },
    });
  } catch (err) {
    throw new ApiError(`Network error: ${(err as Error)?.message ?? String(err)}`);
  }

  const text = await response.text();

  if (!response.ok) {
    try {
      const parsed = JSON.parse(text) as ErrorResponse;
      throw new ApiError(parsed?.error ?? `Request failed with ${response.status}`);
    } catch {
      throw new ApiError(text || `Request failed with ${response.status}`);
    }
  }

  try {
    return JSON.parse(text) as PackResult;
  } catch {
    throw new ApiError('Invalid JSON in API response');
  }
}
website/client/components/Home/TryItResult.vue (1)

37-41: Do not show selection UI when an error is present

Guard the file selection against error state to avoid rendering it alongside errors.

Apply this diff:

-    <TryItFileSelection
-      v-if="result?.metadata?.allFiles && result.metadata.allFiles.length > 0"
+    <TryItFileSelection
+      v-if="!error && result?.metadata?.allFiles && result.metadata.allFiles.length > 0"
       :all-files="result.metadata.allFiles"
       :loading="loading"
       @repack="handleRepack"
     />
website/client/components/Home/TryItFileSelection.vue (3)

43-45: Guard percentage calculations against zero total tokens

When totalTokens is 0, the percentage will render as NaN%. Guard with a zero check.

Apply this diff:

-        {{ selectedTokens.toLocaleString() }} tokens 
-        ({{ ((selectedTokens / totalTokens) * 100).toFixed(1) }}%)
+        {{ selectedTokens.toLocaleString() }} tokens 
+        ({{ totalTokens > 0 ? ((selectedTokens / totalTokens) * 100).toFixed(1) : '0.0' }}%)
-                {{ ((file.tokenCount / totalTokens) * 100).toFixed(1) }}<span class="unit">%</span>
+                {{ totalTokens > 0 ? ((file.tokenCount / totalTokens) * 100).toFixed(1) : '0.0' }}<span class="unit">%</span>

Also applies to: 70-71


120-132: Directly mutating nested props is acceptable here, but consider trade-offs

Mutating file.selected (nested prop) is allowed in Vue 3 and aligns with the goal to preserve selection state. If you want stricter one-way data flow in the future, consider maintaining local state and emitting updates to the parent, at the cost of more boilerplate.


61-62: Remove no-op onFileSelectionChange and related listeners

The no-op handler and calls add noise. Vue reactivity will pick up file.selected mutations without it.

Apply this diff:

-              class="file-checkbox"
-              @change="onFileSelectionChange"
+              class="file-checkbox"
-  onFileSelectionChange();
-  onFileSelectionChange();
-const onFileSelectionChange = () => {
-  // This will trigger reactivity updates
-};
+// (removed: reactivity updates are automatic when mutating `file.selected`)

Also applies to: 124-125, 131-132, 134-136

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 2b04948 and 339d1ab.

📒 Files selected for processing (8)
  • website/client/components/Home/TryIt.vue (4 hunks)
  • website/client/components/Home/TryItFileSelection.vue (1 hunks)
  • website/client/components/Home/TryItResult.vue (1 hunks)
  • website/client/components/api/client.ts (3 hunks)
  • website/client/composables/usePackRequest.ts (3 hunks)
  • website/client/tsconfig.json (1 hunks)
  • website/server/src/remoteRepo.ts (1 hunks)
  • website/server/src/types.ts (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
website/client/composables/usePackRequest.ts (1)
website/client/components/api/client.ts (1)
  • FileInfo (13-18)
website/server/src/types.ts (1)
website/client/components/api/client.ts (1)
  • FileInfo (13-18)
🔇 Additional comments (9)
website/server/src/types.ts (1)

39-41: Addition of allFiles metadata looks good.

The optional allFiles?: FileInfo[] aligns with the new UI flow and keeps the response backward compatible when omitted.

website/client/components/Home/TryIt.vue (2)

96-97: Good wiring of the repack event.

Propagating the repack event from TryItResult into a local handler keeps TryIt.vue in control of the flow without coupling to child internals.


109-109: Type-only import for FileInfo is correct.

Using import type avoids bundling the client API module at runtime.

website/client/composables/usePackRequest.ts (2)

2-2: Importing FileInfo alongside PackResult is appropriate.

Keeps the composable self-contained for typing both inputs and outputs of the repack flow.


208-209: Exposing repackWithSelectedFiles from the composable is the right API surface.

This keeps the Try-It page thin and enables reuse elsewhere if needed.

website/client/components/api/client.ts (2)

13-18: New FileInfo type aligns with UI needs — LGTM

The shape supports path, token/char counts, and optional selection state needed for the checklist UI and repack flow.


40-45: Confirm server guarantees tokenCount in topFiles and allFiles

The client now expects tokenCount on each topFiles entry and allFiles. If the website is ever pointed at an older API, this could break assumptions. If backward compatibility is a concern, consider making tokenCount optional here and guarding in the UI; otherwise, this looks consistent with the server changes described in the PR.

Would you like me to scan the server types and payload construction to ensure tokenCount is always present in both topFiles and allFiles?

website/client/components/Home/TryItResult.vue (1)

26-49: Conditional flow is sensible

  • Error has priority, then result content, then selection UI (conditionally), and finally a loading spinner when appropriate. The independent v-if for the selection panel allows showing it alongside the result, which matches the UX described.
website/client/components/Home/TryItFileSelection.vue (1)

80-93: Public API is clear and composable — LGTM

Props, emits, and the computed structure are clean. Emitting FileInfo[] ties neatly into the repack flow.

@codecov
Copy link

codecov bot commented Aug 19, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.44%. Comparing base (7d1a6f6) to head (cc540ee).
⚠️ Report is 21 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #791   +/-   ##
=======================================
  Coverage   87.44%   87.44%           
=======================================
  Files         113      113           
  Lines        6491     6491           
  Branches     1331     1331           
=======================================
  Hits         5676     5676           
  Misses        815      815           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@yamadashy
Copy link
Owner

Hi, @spandan-kumar !
Thank you for this excellent PR! The implementation looks great at first glance. I'll provide a detailed review later.

The file selection feature with checkbox UI is a solid foundation, and showing token counts for each file is really helpful for users to understand the impact of their selections.

For future iterations, we might consider implementing a tree view interface for more intuitive directory-level operations, but this flat list approach works well as an MVP.

I really appreciate your contribution! 🎉

spandan-kumar and others added 4 commits August 24, 2025 13:02
- Add FileInfo interface for individual file metadata
- Extend PackResult to include allFiles array with complete file information
- Create TryItFileSelection component with checkboxes for each file
- Add bulk selection controls (Select All/Deselect All)
- Implement re-packing functionality for selected files only
- Add live statistics showing selected files and token counts
- Fix TypeScript configuration for proper import.meta.env support
- Add responsive design for mobile and desktop
- Include scrollable file list with proper overflow handling

Resolves the GitHub issue requesting checkboxes for file inclusion/exclusion
on the website UI. Provides tree-based selection interface after initial
packing process as suggested by maintainer.

# Conflicts:
#	website/client/components/Home/TryItResult.vue
The Warp sponsor section was accidentally removed from the loading state
in the file selection feature implementation. This commit restores the
sponsor section with proper styling to maintain the original UX during
repository processing.
Reverts the DEV/PROD logic change in API_BASE_URL back to the standard
pattern used throughout the codebase. The original change was
unintentional and inconsistent with project conventions.
Updates Warp sponsor section with:
- New sponsor URL (go.warp.dev/repomix)
- Updated brand image from Warp's official assets
- Revised messaging emphasizing AI agent support
- Improved loading state layout with sponsor content first
@yamadashy yamadashy force-pushed the feat/website-file-selection-checkboxes branch from 92bf74c to a75248d Compare August 24, 2025 04:06
Reverts TryItResult.vue back to the original design to maintain
consistency with existing UI patterns. Removes the file selection
integration that was disrupting the component's original layout
and styling structure.
Adds essential file selection capabilities while preserving the original
TryItResult design structure:
- Import FileInfo type and TryItFileSelection component
- Add TypeScript interfaces for Props and Emits
- Implement handleRepack function for file re-packing
- Add TryItFileSelection component after result content
- Maintain original styling and layout structure

This provides the core file selection feature without disrupting
the existing UI design patterns.
Separates loading state (spinner + sponsor section) into a dedicated
component to prevent future conflicts:
- Create TryItLoading.vue with loading spinner and Warp sponsor section
- Update TryItResult.vue to use the new loading component
- Remove loading-related CSS from TryItResult.vue
- Improve component separation of concerns

This change isolates sponsor-related updates from core functionality
changes, reducing merge conflicts when sponsor content is updated.
Adjusts RateLimiter configuration to allow more requests during development:
- Development: 10 requests per minute (increased from 3)
- Production: 3 requests per minute (unchanged)

This improves developer experience when testing file selection and
re-packing functionality without being overly restrictive during development.
Add tokenCountTree option to CLI configuration to ensure token counts
are calculated for all files in the repository, not just the top files.
This is required for the file selection feature to display accurate
token statistics for each individual file.

The tokenCountTree option enables complete token count generation
across the entire repository structure, supporting the selective
re-packing functionality.
Add tabbed navigation to switch between result content and file selection:

- Add tab navigation UI with Result and File Selection tabs
- Implement tab switching logic with proper state management
- Use v-show for performance optimization to maintain component state
- Add defensive form submission handling to prevent accidental packing
- Integrate file selection component with repack functionality
- Maintain clean separation between result display and file management

The tabbed interface improves UX by organizing content and preventing
accidental form submissions from UI interaction buttons.
Update repomix package from v1.2.0 to v1.4.0 to support the new
tokenCountTree option and other enhancements required for the
file selection feature.
- Convert file list to table format with clickable rows and compact layout
- Add warning message when selecting more than 500 files
- Increase include patterns limit from 1,000 to 100,000 characters
- Auto-switch to Result tab when Re-pack button is clicked
- Fix re-pack loading state to use shared loading status
- Sort files by token count instead of character count
- Replace Package icon with custom SVG for re-pack button
- Add row hover effects and full-row click selection
- Implement proper file selection state management during re-pack
- Create PackIcon.vue component with configurable size prop
- Replace inline SVG in PackButton.vue with PackIcon component
- Replace inline SVG in TryItFileSelection.vue with PackIcon component
- Improve maintainability and consistency across pack-related UI elements
- Remove unused Package import from lucide-vue-next
- Replace forEach loops with for...of loops for better performance
- Fix import ordering and spacing inconsistencies
- Simplify interface definitions and type declarations
- Add proper padding to tokens column in file selection table
- Remove unnecessary line breaks in computed properties
- Improve code readability and consistency across components
@yamadashy
Copy link
Owner

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a file selection feature, allowing users to choose which files to include in the packed output. The changes are well-structured, with new Vue components for the UI, updates to the API client and server to handle file metadata, and modifications to the usePackRequest composable to manage the re-packing logic.

The implementation is solid, but I've identified a couple of areas for improvement in the new TryItFileSelection.vue component. One is a high-severity issue regarding direct prop mutation, which goes against Vue's best practices. The other is a medium-severity issue concerning an edge case in the UI that could lead to displaying NaN.

Overall, this is a great feature addition. Addressing these points will improve the robustness and maintainability of the new functionality.

Remove redundant border and border-radius from file list container
as the table already provides appropriate visual separation
- Add local reactive state to avoid mutating props directly
- Use deep copying via watch to sync props.allFiles to localFiles
- Remove unnecessary @change handler since v-model handles changes
- This addresses Vue anti-pattern of mutating props identified by code review

Fixes the issue where the component was directly mutating the `selected`
property of files passed via props, which violates Vue's one-way data flow.
…ntainability

- Extract constants: FILE_SELECTION_WARNING_THRESHOLD and TabType to dedicated files
- Extract warning message to reusable FileSelectionWarning component
- Optimize performance: replace deep watch with shallow watch and use structuredClone
- Enhance accessibility: add comprehensive aria-label attributes to all interactive elements
- Strengthen error handling: add zero division protection for percentage calculation
- Improve code quality: enhance comments and maintain consistent type definitions

This refactoring improves code maintainability, performance, and user experience
while following Vue.js and accessibility best practices.
- Add try-catch around structuredClone with JSON fallback
- Fixes DataCloneError in environments where structuredClone fails
- Ensures compatibility across different browser environments
@yamadashy yamadashy force-pushed the feat/website-file-selection-checkboxes branch from aceb45e to 7ff2e00 Compare August 24, 2025 07:29
@yamadashy
Copy link
Owner

@spandan-kumar
I've adjusted the UI and behavior.
It now displays in separate tabs, and the loading status indicator and other aspects now behave similarly to the existing Pack processing.

image

I'll merge it as is!
Thank you for your cooperation!

@yamadashy yamadashy merged commit b562099 into yamadashy:main Aug 24, 2025
135 of 145 checks passed
@spandan-kumar
Copy link
Contributor Author

Looks great, kudos man! Happy to contribute.
@yamadashy

@spandan-kumar spandan-kumar deleted the feat/website-file-selection-checkboxes branch August 28, 2025 05:09
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.

feat: checklist on the website for including or excluding files from github

2 participants