Skip to content

Conversation

@pushpak1300
Copy link
Member

@pushpak1300 pushpak1300 commented Feb 6, 2026

Summary

  • Guidelines hardcoded resources/js/Pages (PascalCase), but some projects use resources/js/pages (lowercase). This caused AI assistants to create or reference files in the wrong directory.
  • Added a pagesDirectory() method that detects the actual casing from disk using scandir(), which works reliably on case-insensitive filesystems like macOS.
  • Updated all 7 Inertia Blade templates to use the detected directory instead of the hardcoded path.
  • Fixed a stale test in CodexTest that expected .codex/skills instead of .agents/skills after the unified paths change.

How To Test

  • Run composer test — all tests pass
  • Verify on a project with resources/js/pages (lowercase) that guidelines output the correct path
  • Verify on a project with resources/js/Pages (PascalCase) that guidelines output the correct path

@pushpak1300 pushpak1300 merged commit dfedb54 into main Feb 6, 2026
18 checks passed
@pushpak1300 pushpak1300 deleted the fix_pages_directory branch February 6, 2026 10:38
@dani-vrd
Copy link

dani-vrd commented Feb 9, 2026

@pushpak1300

Improve $assist->inertia()->pagesDirectory() to support multiple and nested page directories.

Problem

The current pagesDirectory() method is too limited:

  1. Only scans root level - Doesn't check subdirectories like resources/js/web/pages or resources/js/cms/pages
  2. Single directory only - Can't return multiple page directories
  3. Ignores Inertia config - Doesn't read from config/inertia.php (the source of truth)
  4. Hardcoded fallback - Returns resources/js/Pages regardless of actual project structure

Real-world scenarios not covered

Many projects use multiple page directories:

  • resources/js/web/pages (public website)
  • resources/js/admin/pages (admin panel)
  • resources/js/cms/Pages (different casing)
  • Any custom structure specified in config/inertia.php

Proposed Solution

Enhanced pagesDirectory() method:

/**
* Get Inertia pages directory/directories.
*
* Returns string if single directory, array if multiple.
* Reads from config/inertia.php first, then scans filesystem.
*
* @return string|array<string>
*/
public function pagesDirectory(): string|array
{
    // 1. Try reading from config (source of truth)
    $configPaths = $this->getPagesFromConfig();
    if (! empty($configPaths)) {
        return count($configPaths) === 1
            ? $this->relativePath($configPaths[0])
            : array_map([$this, 'relativePath'], $configPaths);
    }

    // 2. Fallback: Scan filesystem recursively
    $foundPaths = $this->scanForPagesDirectories();
    if (! empty($foundPaths)) {
        return count($foundPaths) === 1
            ? $foundPaths[0]
            : $foundPaths;
    }

    // 3. Ultimate fallback
    return 'resources/js/Pages';
}

/**
* Get page paths from config/inertia.php
*
* @return array<string>
*/
private function getPagesFromConfig(): array
{
    $configFile = base_path('config/inertia.php');

    if (! file_exists($configFile)) {
        return [];
    }

    try {
        $config = include $configFile;
        $paths = [];

        // Get production page_paths
        if (isset($config['page_paths']) && is_array($config['page_paths'])) {
            $paths = array_merge($paths, $config['page_paths']);
        }

        // Get testing page_paths (might be different)
        if (
            isset($config['testing']['page_paths']) && is_array($config['testing']['page_paths'])) {
            $testPaths = $config['testing']['page_paths'];
            // Add only if different from production
            foreach ($testPaths as $testPath) {
                if (! in_array($testPath, $paths, true)) {
                    $paths[] = $testPath;
                }
            }
        }

        // Filter out non-existent directories
        return array_filter($paths, fn ($path) => is_dir($path));
    } catch (\Throwable $e) {
        return [];
    }
}

/**
* Recursively scan for 'pages' or 'Pages' directories
*
* @return array<string>
*/
private function scanForPagesDirectories(): array
{
    $jsPath = base_path('resources/js');

    if (! is_dir($jsPath)) {
        return [];
    }

    $found = [];
    $iterator = new \RecursiveIteratorIterator(
        new \RecursiveDirectoryIterator($jsPath, \FilesystemIterator::SKIP_DOTS),
        \RecursiveIteratorIterator::SELF_FIRST
    );

    foreach ($iterator as $file) {
        if ($file->isDir()) {
            $dirname = $file->getBasename();

            // Match 'pages' or 'Pages'
            if (in_array($dirname, ['pages', 'Pages'], true)) {
                $found[] = $this->relativePath($file->getPathname());
            }
        }
    }

    // Sort by depth (prefer shallower paths first)
    usort($found, fn ($a, $b) => substr_count($a, '/') <=> substr_count($b, '/'));

    return $found;
}

/**
* Convert absolute path to relative path from base_path()
*/
private function relativePath(string $absolutePath): string
{
    $basePath = base_path();

    if (str_starts_with($absolutePath, $basePath)) {
        return ltrim(substr($absolutePath, strlen($basePath)), '/\\');
    }

    return $absolutePath;
}

Benefits

  1. Reads from config first - Respects config/inertia.php as source of truth
  2. Supports multiple directories - Returns array when multiple page dirs exist
  3. Recursive scanning - Finds nested directories like resources/js/web/pages
  4. Case insensitive - Handles both pages and Pages
  5. Filters non-existent - Only returns directories that actually exist
  6. Backward compatible - Returns single string when only one directory exists
  7. Graceful fallback - Still works if config doesn't exist

Example Output

Single directory project:

$assist->inertia()->pagesDirectory()
// Returns: "resources/js/Pages"

Multi-directory project:

$assist->inertia()->pagesDirectory()
// Returns: [
// "resources/js/web/pages",
// "resources/js/cms/pages"
// ]

### Impact

This improvement makes the Boost assistant more accurate for real-world Laravel projects that use multiple Inertia page directories, providing better guidance to AI assistants.

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