Skip to content

Project path#1

Open
roman3t wants to merge 2 commits intoSegun-io:mainfrom
roman3t:project-path
Open

Project path#1
roman3t wants to merge 2 commits intoSegun-io:mainfrom
roman3t:project-path

Conversation

@roman3t
Copy link
Collaborator

@roman3t roman3t commented Jan 20, 2026

Summary by CodeRabbit

Release Notes

  • New Features

    • Improved project creation dialog with enhanced path validation and selection responsiveness.
  • Chores

    • Refactored internal component styling architecture.
    • Restructured router configuration for improved maintainability.
    • Updated development dependencies.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 24, 2026

📝 Walkthrough

Walkthrough

The PR reorganizes router configuration into a dedicated module, refactors button styling into a separate utility file, and introduces race-safe path validation in the project sidebar to prevent stale state updates. Minor configuration updates include ignoring the prettier config file and updating a submodule pointer.

Changes

Cohort / File(s) Summary
Router Refactoring
src/router.ts, src/router.tsx
Extracted router initialization and context setup into a dedicated module (src/router.ts) with TanStack React Router configuration. src/router.tsx simplified to a wrapper component that imports and renders the router.
Button Styling Extraction
src/components/ui/button-variants.ts, src/components/ui/button.tsx
Moved buttonVariants CVA configuration to a new utility module. button.tsx updated to import variants instead of defining them inline, eliminating code duplication.
Project Sidebar Path Validation
src/components/project-sidebar.tsx
Introduced race-safe path validation using a sequencing counter to prevent stale validation results from overwriting state. Added skipNextDebounce flag for immediate updates via Browse button. Refactored validation flow with debounce adjustments and minor JSX formatting consistency updates.
Configuration & Metadata
.gitignore, src-tauri/As
Added .prettierrc to gitignore with comment header. Updated submodule pointer for src-tauri/As to commit b2cc6d8eb9eaf4d994856bade5a38bbca2de42b6.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A router hops to its own file,
Buttons shed their style with humble smile,
Path validation races tamed with care,
State sequences dance through the air!
~CodeRabbit 🌟

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Project path' is vague and generic, using non-descriptive terminology that doesn't convey meaningful information about the changeset's primary objective. Consider a more specific title like 'Fix project path revalidation after browsing folder' or 'Add race-safe path validation to CreateProjectDialog' that clearly describes the main change.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

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

@angelsantosa
Copy link
Contributor

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Jan 24, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@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: 3

🤖 Fix all issues with AI agents
In `@src-tauri/As`:
- Line 1: The repository contains a broken submodule declaration for path
"src-tauri/As" pointing at commit b2cc6d8eb9eaf4d994856bade5a38bbca2de42b6; fix
by either: (A) restoring it as a real submodule — add a .gitmodules entry with
the correct URL for the As subrepo, commit the .gitmodules change, run git
submodule init && git submodule update --init --recursive to populate
src-tauri/As (ensure its .git data exists and the commit b2cc6d8… is fetchable),
or (B) remove the broken submodule declaration and make it a normal folder —
remove the submodule from the index (git rm --cached src-tauri/As), delete any
stale gitlink entry, commit the removal of the submodule entry and .gitmodules
if present, then re-add the directory contents as normal files; choose the
appropriate option and commit the resulting changes so other developers can
clone and update without errors.

In `@src/components/project-sidebar.tsx`:
- Around line 334-350: When the effect early-returns due to
skipNextDebounce.current, it leaves stale validation UI state; update the
early-return branch in the useEffect (the one referencing
skipNextDebounce.current) to also reset validation state by calling
setPathWarning(null) and setIsValidatingPath(false) (while still clearing
skipNextDebounce.current = false), so any code path that sets skipNextDebounce
without going through handleBrowseNew won't leave stale state; reference the
useEffect, skipNextDebounce, setPathWarning, setIsValidatingPath,
validateNewPath, and handleBrowseNew symbols when making the change.

In `@src/components/ui/button.tsx`:
- Around line 1-28: The module no longer re-exports buttonVariants causing
imports like import { buttonVariants } from "@/components/ui/button" to break;
update src/components/ui/button.tsx to re-export the variant helper by adding a
top-level export for buttonVariants (export { buttonVariants } from
"./button-variants") so existing consumers (e.g., alert-dialog.tsx) continue to
work while keeping the Button component and its forwardRef intact.

@@ -0,0 +1 @@
Subproject commit b2cc6d8eb9eaf4d994856bade5a38bbca2de42b6
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# Check git configuration and submodule status
git config --file=.gitmodules --get-regexp path

Repository: Segun-io/ada

Length of output: 38


🏁 Script executed:

# List files in the repository to understand structure
git ls-files | grep -E "(\.gitmodules|src-tauri)" | head -20

Repository: Segun-io/ada

Length of output: 698


🏁 Script executed:

# Check if src-tauri/As is a submodule by examining git index
git ls-files --stage | grep "src-tauri/As"

Repository: Segun-io/ada

Length of output: 118


🏁 Script executed:

# Get the current submodule status
git submodule status 2>&1 || echo "No submodules or command failed"

Repository: Segun-io/ada

Length of output: 160


🏁 Script executed:

# Check if .gitmodules exists
ls -la .gitmodules 2>&1 || echo ".gitmodules does not exist"

Repository: Segun-io/ada

Length of output: 141


🏁 Script executed:

# Check the content of src-tauri/As file itself
cat -n src-tauri/As 2>&1 || echo "Cannot read as regular file"

Repository: Segun-io/ada

Length of output: 117


🏁 Script executed:

# Check git status for src-tauri/As
git status src-tauri/As 2>&1

Repository: Segun-io/ada

Length of output: 121


🏁 Script executed:

# Check recent commits mentioning As or submodule
git log --oneline --all -- src-tauri/As 2>&1 | head -10

Repository: Segun-io/ada

Length of output: 79


🏁 Script executed:

# List contents of src-tauri/As
ls -la src-tauri/As

Repository: Segun-io/ada

Length of output: 164


🏁 Script executed:

# Check if it has .git directory
[ -d "src-tauri/As/.git" ] && echo "Has .git" || echo "No .git"

Repository: Segun-io/ada

Length of output: 63


🏁 Script executed:

# Get more details about the git object
git rev-parse b2cc6d8eb9eaf4d994856bade5a38bbca2de42b6 2>&1 || echo "Commit not accessible"

Repository: Segun-io/ada

Length of output: 96


🏁 Script executed:

# Show the commit details for the hash
git log -1 --oneline b2cc6d8eb9eaf4d994856bade5a38bbca2de42b6

Repository: Segun-io/ada

Length of output: 229


🏁 Script executed:

# Show commit message
git log -1 --format="%B" b2cc6d8eb9eaf4d994856bade5a38bbca2de42b6

Repository: Segun-io/ada

Length of output: 229


🏁 Script executed:

# Check if there's a HEAD or recent history that shows what happened with As
git log --oneline --all -20 -- src-tauri/As

Repository: Segun-io/ada

Length of output: 79


Fix incomplete submodule configuration.

The submodule at src-tauri/As is broken and will prevent team members from properly cloning and using the repository:

  • Missing .gitmodules: No .gitmodules configuration file exists, yet the git index declares this directory as a submodule (mode 160000).
  • Empty directory: The src-tauri/As directory is empty with no .git directory, indicating the submodule was never initialized.
  • Inaccessible commit: The commit hash b2cc6d8eb9eaf4d994856bade5a38bbca2de42b6 points to an external repository but cannot be fetched because the submodule is not properly configured.

This configuration will cause git submodule commands to fail for team members. Either:

  1. Add a proper .gitmodules entry for this submodule and initialize it, or
  2. Remove the submodule declaration from the index if this directory should be a regular folder in the repository.
🤖 Prompt for AI Agents
In `@src-tauri/As` at line 1, The repository contains a broken submodule
declaration for path "src-tauri/As" pointing at commit
b2cc6d8eb9eaf4d994856bade5a38bbca2de42b6; fix by either: (A) restoring it as a
real submodule — add a .gitmodules entry with the correct URL for the As
subrepo, commit the .gitmodules change, run git submodule init && git submodule
update --init --recursive to populate src-tauri/As (ensure its .git data exists
and the commit b2cc6d8… is fetchable), or (B) remove the broken submodule
declaration and make it a normal folder — remove the submodule from the index
(git rm --cached src-tauri/As), delete any stale gitlink entry, commit the
removal of the submodule entry and .gitmodules if present, then re-add the
directory contents as normal files; choose the appropriate option and commit the
resulting changes so other developers can clone and update without errors.

Comment on lines 334 to 350
useEffect(() => {
const activeTab = form.state.values.activeTab
const newPath = form.state.values.newPath

if (skipNextDebounce.current) {
skipNextDebounce.current = false
return
}

if (activeTab === "new" && newPath) {
const timeoutId = setTimeout(() => {
validateNewPath(newPath)
}, 300)
const timeoutId = setTimeout(() => validateNewPath(newPath), 300)
return () => clearTimeout(timeoutId)
} else {
setPathWarning(null)
setIsValidatingPath(false)
}
}, [form.state.values.activeTab, form.state.values.newPath, validateNewPath])
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider resetting state when debounce is skipped.

When skipNextDebounce is true, the effect returns early without clearing potential stale state. While handleBrowseNew already sets these states before triggering validation, consider if there are other code paths that could set skipNextDebounce without also managing state.

Currently this works correctly because handleBrowseNew is the only setter of skipNextDebounce, but this coupling is implicit.

💡 Optional: Add a comment documenting the coupling
   useEffect(() => {
     const activeTab = form.state.values.activeTab
     const newPath = form.state.values.newPath
 
     if (skipNextDebounce.current) {
       skipNextDebounce.current = false
-      return
+      return // handleBrowseNew already triggered validation directly
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
useEffect(() => {
const activeTab = form.state.values.activeTab
const newPath = form.state.values.newPath
if (skipNextDebounce.current) {
skipNextDebounce.current = false
return
}
if (activeTab === "new" && newPath) {
const timeoutId = setTimeout(() => {
validateNewPath(newPath)
}, 300)
const timeoutId = setTimeout(() => validateNewPath(newPath), 300)
return () => clearTimeout(timeoutId)
} else {
setPathWarning(null)
setIsValidatingPath(false)
}
}, [form.state.values.activeTab, form.state.values.newPath, validateNewPath])
useEffect(() => {
const activeTab = form.state.values.activeTab
const newPath = form.state.values.newPath
if (skipNextDebounce.current) {
skipNextDebounce.current = false
return // handleBrowseNew already triggered validation directly
}
if (activeTab === "new" && newPath) {
const timeoutId = setTimeout(() => validateNewPath(newPath), 300)
return () => clearTimeout(timeoutId)
} else {
setPathWarning(null)
setIsValidatingPath(false)
}
}, [form.state.values.activeTab, form.state.values.newPath, validateNewPath])
🤖 Prompt for AI Agents
In `@src/components/project-sidebar.tsx` around lines 334 - 350, When the effect
early-returns due to skipNextDebounce.current, it leaves stale validation UI
state; update the early-return branch in the useEffect (the one referencing
skipNextDebounce.current) to also reset validation state by calling
setPathWarning(null) and setIsValidatingPath(false) (while still clearing
skipNextDebounce.current = false), so any code path that sets skipNextDebounce
without going through handleBrowseNew won't leave stale state; reference the
useEffect, skipNextDebounce, setPathWarning, setIsValidatingPath,
validateNewPath, and handleBrowseNew symbols when making the change.

Comment on lines +1 to +28
import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import type { VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
import { buttonVariants } from "./button-variants";

export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
extends
React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean
asChild?: boolean;
}

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button"
const Comp = asChild ? Slot : "button";
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
)
);
}
)
Button.displayName = "Button"
);
Button.displayName = "Button";

export { Button, buttonVariants }
export { Button };
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if any files import buttonVariants from button.tsx (not button-variants.ts)
rg -n "from ['\"].*button['\"]" --type ts --type tsx | grep -i "buttonVariants" || echo "No direct imports of buttonVariants from button.tsx found"

Repository: Segun-io/ada

Length of output: 158


🏁 Script executed:

#!/bin/bash
# Also check with different quote patterns and search specifically for button imports
rg -n "buttonVariants.*from" --type ts --type tsx | head -30

Repository: Segun-io/ada

Length of output: 83


🏁 Script executed:

#!/bin/bash
# Check if button.tsx previously exported buttonVariants (look at git history or check current state)
git log --oneline -n 20 -- src/components/ui/button.tsx 2>/dev/null || echo "No git history available"

Repository: Segun-io/ada

Length of output: 79


🏁 Script executed:

#!/bin/bash
# List all files in the ui components directory to understand structure
fd -e ts -e tsx src/components/ui/ | head -20

Repository: Segun-io/ada

Length of output: 433


🏁 Script executed:

#!/bin/bash
# List all files in the ui components directory
fd . 'src/components/ui/'

Repository: Segun-io/ada

Length of output: 520


🏁 Script executed:

#!/bin/bash
# Search for all imports of buttonVariants across the entire codebase
rg "buttonVariants" -g '!node_modules' | head -50

Repository: Segun-io/ada

Length of output: 632


🏁 Script executed:

#!/bin/bash
# Check if button-variants file exists and read it
fd -e ts -e tsx 'button-variants' || echo "File not found"

Repository: Segun-io/ada

Length of output: 92


🏁 Script executed:

#!/bin/bash
# Search specifically for import statements that include buttonVariants
rg "import.*buttonVariants" | head -20

Repository: Segun-io/ada

Length of output: 227


Critical: Add re-export for backward compatibility

The refactoring creates a breaking change. The file src/components/ui/alert-dialog.tsx currently imports buttonVariants from @/components/ui/button (line showing: import { buttonVariants } from "@/components/ui/button"), but the new button.tsx no longer exports it—only button-variants.ts does.

Add this re-export to src/components/ui/button.tsx to prevent breaking the existing import:

export { buttonVariants } from "./button-variants";

Without this, alert-dialog.tsx will fail to import buttonVariants.

🤖 Prompt for AI Agents
In `@src/components/ui/button.tsx` around lines 1 - 28, The module no longer
re-exports buttonVariants causing imports like import { buttonVariants } from
"@/components/ui/button" to break; update src/components/ui/button.tsx to
re-export the variant helper by adding a top-level export for buttonVariants
(export { buttonVariants } from "./button-variants") so existing consumers
(e.g., alert-dialog.tsx) continue to work while keeping the Button component and
its forwardRef intact.

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.

2 participants