Set up end-to-end browser testing using Pest Browser Plugin + Playwright.
New v4 test suite uses SQLite :memory: database with pre-generated schema dump
(database/schema/testing-schema.sql) instead of running migrations, enabling
faster test startup.
- Add pestphp/pest-plugin-browser dependency
- Create GenerateTestingSchema command to export PostgreSQL schema to SQLite
- Add .env.testing configuration for isolated test environment
- Implement v4 test directory structure (Feature, Browser, Unit tests)
- Update Pest skill documentation with browser testing patterns, API reference,
debugging techniques, and common pitfalls
- Configure phpunit.xml and tests/Pest.php for v4 suite
- Update package.json and docker-compose.dev.yml for testing dependencies
- Introduced a new sidebar component for service database navigation.
- Updated routes for database import and backup functionalities.
- Refactored the database import view to improve clarity and maintainability.
- Consolidated service application and database views into a more cohesive structure.
- Removed deprecated service application view and integrated its functionalities into the service index.
- Enhanced user experience with modal confirmations for critical actions.
- Improved code readability and organization across various components.
The livewire:init event fires before inline scripts execute in Livewire
components, so wrapping Livewire.on() in document.addEventListener('livewire:init')
prevents the callback from ever firing, breaking chart data updates.
This removes the wrapper to match the working pattern in metrics.blade.php.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Wraps inline chart initialization scripts in IIFEs to create local scope for variables. This prevents "Identifier has already been declared" errors when Livewire's SPA navigation re-executes scripts, allowing smooth navigation between metrics pages without page refresh.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Add visual feedback when downloading all logs in both container and deployment log views. Users now see an animated spinner and "Downloading..." text, preventing multiple concurrent downloads and improving UX during long operations.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Adjusted indentation and formatting for better code clarity.
- Simplified conditional statements and removed unnecessary null checks.
- Enhanced user interface elements for Docker Compose and Dockerfile configurations.
- Improved handling of deployment commands and network settings.
- Updated helper texts for better user guidance.
Users can now choose between downloading only the currently displayed
logs or fetching and downloading all available logs from the container.
Changes:
- Add downloadAllLogs() method that fetches all logs without limit
- Replace download button with dropdown menu
- Options: "Download displayed logs" and "Download all logs"
Addresses #7803
The log viewer was artificially limiting display to 2000 lines
regardless of user's requested amount. Users could request 10k, 40k,
or 50k lines but only 2000 were ever shown.
Changes:
- Remove the hardcoded $maxDisplayLines = 2000 limit in the view
- Add MAX_LOG_LINES constant (50,000) in GetLogs component
- Enforce maximum limit in backend to prevent extremely large requests
- Update input field with max attribute and tooltip
Fixes#7803
Add smart goBack() method that skips auto-selected steps and returns to the
last step where user had a real choice. This prevents navigation loops when
previous steps only have a single option and auto-select.
Fixes#7739🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit introduces advanced environment variable handling capabilities including:
- Nested environment variable resolution with circular dependency detection
- Extraction of hardcoded environment variables from docker-compose.yml
- New ShowHardcoded Livewire component for displaying detected variables
- Enhanced UI for better environment variable management
The changes improve the user experience by automatically detecting and displaying
environment variables that are hardcoded in docker-compose files, allowing users
to override them if needed. The nested variable resolution ensures complex variable
dependencies are properly handled.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Use x-callout component in developer view for env var note
- Simplify label text from "Comment (Optional)" to "Comment"
- Minor code formatting improvements via Pint
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Moved the Update button to appear inline with the comment field for better UX when editing comments on locked environment variables. The button now appears on the same row as the comment input on larger screens.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Removed the duplicate delete button that was appearing at the bottom of locked environment variables. The delete button at the top (next to the lock icon) is sufficient.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Removed instantSave from comment field and added a proper Update button with Delete modal for locked environment variables. This ensures users can explicitly save their comment changes on locked variables.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Modified the locked environment variable view to keep the comment field editable even when the variable value is locked. Users with update permission can now edit comments on locked variables, while users without permission can still view the comment for reference.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
When an environment variable is locked (is_shown_once=true), the comment field is now displayed as disabled/read-only for future reference. This allows users to see the documentation/note about what the variable is for, even when the value is hidden for security.
The comment field appears after the key field and before the configuration checkboxes in the locked view.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add comment field support to the "New Shared Variable" modal, ensuring it's saved properly for both normal and shared environment variables at all levels (Team, Project, Environment).
Changes:
- Add comment property, validation, and dispatch to Add component (Livewire & view)
- Update saveKey methods in Team, Project, and Environment to accept comment
- Replace SharedEnvironmentVariable model's $guarded with explicit $fillable array
- Include comment field in creation flow for all shared variable types
The comment field (max 256 chars, optional) is now available when creating shared variables and is consistently saved across all variable types.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add comment field to EnvironmentVariable model and database
- Update parseEnvFormatToArray to extract inline comments from env files
- Update Livewire components to handle comment field
- Add UI for displaying and editing comments
- Add tests for comment parsing functionality
Changed from '2025-Dec-18 11:39:13.685710' to '2025-Dec-18 11:39:13'.
Microseconds are still used in wire:key for uniqueness.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Shows a subtle loading indicator over the logs container during refresh
or when enabling streaming. This masks any brief visual glitches from
Livewire's DOM morphing when log content changes significantly.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added morph.added hook to apply color highlighting when logs are first
loaded. The morph.updated hook only fires on subsequent updates, not
on initial DOM insertion.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Applies the same fix from deployment logs to runtime logs (GetLogs component).
Prevents HTML entities like " from appearing when search highlighting
is applied to logs containing special characters.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The hook was preventing new logs from appearing when text was selected.
The hasActiveLogSelection() check in highlightText() is sufficient.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Remove per-line x-effect directives that re-evaluated for every log line during polling
- Replace with efficient applySearch() function that updates logs once after Livewire morph
- Remove unnecessary caching mechanisms (renderTrigger, decodeCache, matchCountCache)
- Remove double HTML encoding of log lines (e() + Blade escaping)
- Add decodeHtml() helper to properly decode HTML entities from data attributes
- Use morph.updated hook instead of commit hook for efficient DOM updates
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Create new Server/Swarm.php Livewire component and view for Swarm configuration
- Create new Server/Sentinel.php Livewire component and view for Sentinel settings
- Add server.swarm and server.sentinel routes
- Move Swarm and Sentinel sections from General page to sidebar menu items
- Improve organization by separating concerns into dedicated pages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Change "Validate Token" to "Validate" and "Delete Token" to "Delete" for cleaner UI.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Use atomic update pattern in backend: collect logs into temp variable
before replacing outputs (prevents empty state flash)
- Remove per-line x-effect directives that caused 4000+ reactive
evaluations on every update
- Replace inline Alpine.js class bindings with CSS utility classes
- Use single $watch and morph.updated hook instead of renderTrigger
- Remove HTML entity decode cache (no longer needed)
- Fix search highlight padding that caused text shifting
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use dataset.logContent instead of textContent for counting search
matches in getMatchCount(). This aligns the counting logic with
matchesSearch() which uses the same data attribute for filtering
visibility, ensuring the displayed match count accurately reflects
the number of visible/hidden lines.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use CSS content-visibility: auto for lazy rendering of off-screen log lines
- Replace setInterval auto-scroll with requestAnimationFrame for smoother scrolling
- Cache HTML entity decoding to avoid repeated DOMParser calls (up to 5000 entries)
- Cache match count calculations to prevent repeated DOM queries
- Debounce search input (300ms) in deployment logs view
- Debounce Livewire render updates (100ms) to batch rapid changes
- Add log-line utility class with content-visibility optimization
- Add log-highlight utility class for search result highlighting
These changes address browser freezing when viewing deployment logs with
3500+ lines (GitHub issue #7668). The content-visibility CSS property lets
the browser skip rendering of off-screen content, significantly reducing
initial render time and memory usage.
Fixes#7668
Add copy-to-clipboard functionality for both deployment logs and runtime container logs with success notification. Fixed event dispatch to use Livewire.dispatch() for proper toast notification handling. Reorganized copy and download buttons to appear consecutively in runtime logs toolbar.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
The Resources tab threw a "Queueing collections with multiple model types is not supported" error because the Livewire component was storing a mixed-type Eloquent collection (Applications, Databases, Services) as a public property, causing Livewire's serialization to fail.
Fixed by: storing only the unmanaged containers array in the component, and calling definedResources() directly in the Blade view for the managed tab.
Fixes#7666🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Logs views should not use Livewire navigation, similar to terminal views.
This ensures full page loads when navigating to logs instead of SPA-like transitions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Remove wireNavigate() from:
- External links (docs, GitHub) - can't be handled by Livewire SPA
- url()->previous() in all error pages - dynamic URL can't prefetch
- Links with target="_blank" - conflicts with wire:navigate semantics
Keep wireNavigate() on internal Dashboard links in error pages.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add SPA navigation with prefetching to all navigation links in the
breadcrumbs component dropdown menus, excluding Terminal links which
require full page loads for WebSocket connections.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add wire:navigate.hover to application, database, and service cards on the environment resource index page for SPA navigation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Implement instance-wide SPA navigation toggle that enables smooth page transitions with prefetching on hover. Excludes terminal links which require full page lifecycle for WebSocket connections. Adds defensive checks to global-search component for SPA navigation compatibility.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Set modal width to consistent 48rem for both upgrade states
- Remove max-width constraint from progress stepper
- Add dev mode with Simulate button for local testing
- Simulate cycles through all upgrade steps with 2-second delays
- Updated dropdown toggle logic to use a single toggle function for better readability.
- Replaced span elements with buttons for dropdown toggles to enhance accessibility.
- Added click outside functionality to close dropdowns when clicking outside.
- Adjusted styling for dropdowns and hover states to use neutral colors for better UI consistency.
- Ensured proper alignment and positioning of dropdowns to prevent overflow issues.
- Removed unnecessary SVG icons from the environment edit view for cleaner UI.
- Deleted the environment select component as it was no longer needed.
- Enhanced the project resource index view with a dropdown for environments and resources, improving navigation.
- Implemented dynamic dropdowns for environments and their associated resources, allowing for better user interaction.
- Added transitions and hover effects for a more responsive design.
- Updated the layout to ensure a consistent user experience across different project resources.
Add a copy button to individual container logs that strips sensitive
data before copying to clipboard. Includes sanitization for emails,
database URLs with passwords, JWT tokens, API keys, private key blocks,
and git access tokens.
Reorder toolbar buttons so that Refresh and Stream Logs (polling)
are adjacent, making the related actions easier to find.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use Livewire's morph.updating hook to skip DOM morphing of the logs
container when user has text selected. This prevents the selection from
being lost when polling or manual refresh occurs.
The previous fix only prevented the JavaScript-based re-render, but
Livewire's morphing was still replacing the DOM elements entirely.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Apply the same selection preservation fix to the runtime logs component
(get-logs.blade.php) that was applied to deployment logs:
- Add hasActiveLogSelection() helper to detect active text selection
- Skip re-render when user has text selected (preserves copy ability)
- Add renderTrigger mechanism to ensure filtering works after refresh
- Use x-effect for hidden state to properly react to Livewire updates
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Ensure initial render happens even when selection is active by checking
if element already has content before skipping re-render.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Prevent text selection from being cleared when logs are re-rendered during polling
- Preserve fullscreen state when toggling debug logs or other Livewire updates
- Fix log filtering to properly apply when debug mode is toggled
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Fix null-safe operator on currentTeam() call in Upgrade.php
- Add --rm flag to docker run in upgrade.sh for cleanup consistency
- Store beforeunload handler as named reference and clean up on success
- Add clarifying comments for upgrade method calls
- Add error state handling with close option in upgrade modal
- Add step mapping documentation comment in upgrade-progress component
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove /api/upgrade-status endpoint and route
- Add getUpgradeStatus() method to Upgrade Livewire component
- Update frontend to call Livewire method via $wire.getUpgradeStatus()
- Simpler approach: no separate API, auth handled by Livewire
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add auth:sanctum middleware to /api/upgrade-status route
- Check user belongs to root team (id 0) before returning status
- Return 403 if user is not authorized
- Update frontend to send credentials with fetch request
- Update OpenAPI docs with 401/403 responses
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- upgrade.sh now writes status to /data/coolify/source/.upgrade-status
- New /api/upgrade-status endpoint reads status file for real progress
- Frontend polls status API instead of simulating progress
- Falls back to health check when service goes down during restart
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove changelog preview section to streamline the UI
- Simplify warning message
- Add reference to upgrade logs location on server
- Minor formatting improvements
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>