Skip to content

Consolidate frontend tooling with Vite+ and fix dashboard request lifecycles - #706

Merged
binaryfire merged 16 commits into
0.4from
chore/vite-plus
Oct 28, 2026
Merged

binaryfire merged 16 commits into
0.4from
chore/vite-plus

Conversation

@binaryfire

@binaryfire binaryfire commented Oct 28, 2026 •

Copy link
Copy Markdown
Member

The framework frontends currently use separate installations, lockfiles and build commands. This makes shared dependency updates harder to maintain and allows the dashboards and other shipped assets to drift. This change puts their development tooling in one Vite+/pnpm workspace and fixes dashboard request and cleanup bugs found while validating the migration.

Shared tooling

  • Include Horizon, Telescope, the exception renderer, Workbench, Wayfinder and the AI workbench in the root workspace. Shared dependencies use a catalog and one lockfile; each package still declares its own dependencies and build configuration.
  • Pin Vite+ and its matching toolchain, preserve the release-age policy, and remove superseded npm locks and configuration. Workbench retains its supported Tailwind major.
  • Provide root formatting, linting, type checking, test and build commands through native Vite+ tools. Quality checks generate Wayfinder fixtures first, so they work after a fresh installation.
  • Keep application skeletons independent. Composer consumers still receive committed, ready-to-use assets and do not need Node or the root catalog. Frontend customization happens in the components repository or with an explicitly configured split fork.
  • Keep mechanical formatting in its own commit and record it in .git-blame-ignore-revs. Existing component names, Options API organization and upstream structure remain recognizable.

Dashboard fixes

Horizon polling now waits for its requests and skips overlapping ticks. Dashboard refreshes wait for every request to settle, including when one fails. List screens cancel superseded reads and reads belonging to a screen that has been left, skip refreshes during user loads, and clear search timers on unmount.

Failed-job searches reset pagination and encode their parameters correctly. Tagged pagination uses the same starting index for selection and returned rows. Navigation remounts resource screens when the path changes while preserving query-only updates. Failed retries release their pending state and explain that the result could not be confirmed.

Modal instances, listeners and timers are cleaned up on unmount. Chart.js instances remain non-reactive so their animation cleanup uses the correct object identity. Horizon uses the supported Bootstrap line while keeping its own light and dark themes.

Telescope updates recording state only after a successful response, prevents overlapping toggles, and reloads cleared entries only after success. Both dashboards update monitoring tags after successful requests and preserve newer input drafts. Telescope stores monitored tags with a native upsert to avoid concurrent duplicate-key failures. All shipped database grammars support this; custom connection grammars need upsert support.

CI and maintenance

Prompts now matches Symfony Console's case-insensitive built-in style names when measuring text and preserving closing tags. It requires Console 8.1.10, where that behavior was fixed. Cookie enum-name coverage follows native Symfony validation across supported versions, including versions that accept 0 as a cookie name; cookie runtime behavior is unchanged.

One JavaScript job installs the frozen workspace, checks source, builds assets, verifies committed outputs, and runs the registered tests and Wayfinder type checks. Asset verification catches both modified files and new untracked chunks, with instructions for rebuilding them. CI does not publish or commit generated files.

Dependabot updates the workspace catalog and independent skeleton separately, with coupled toolchain updates grouped. Contributor documentation covers installation, commands, dependency updates and asset regeneration. Contributors can submit source changes; maintainers regenerate assets before merging.

Verification

  • PHP formatting and static analysis passed, along with affected Horizon, Telescope, Foundation, Workbench, Wayfinder and MCP tests.
  • Shared JavaScript checks and tests passed, including cached Wayfinder routes and generated TypeScript output.
  • Frozen installation and every workspace build passed. Repeated builds produced identical distributed output, and the stale-asset check detected both modifications and added chunks.
  • Browser checks exercised the built dashboards, exception page, Workbench and AI demo, including navigation, modal cleanup, themes and chart cleanup. The demo used intercepted responses without contacting providers.
  • An exported application installed and built independently of the workspace. Bundle sizes were compared, workflow configuration was checked, and the workspace dependency audit reported no advisories.

Note

Migrate frontend monorepo to Vite+ and fix Horizon/Telescope request lifecycles

  • Replaces Vite/Vitest with vite-plus across the workspace: root vite.config.ts defines shared formatting, lint, and test projects for Wayfinder, Horizon, Telescope, and MCP; package scripts and CI (tests.yml) now use vp commands
  • Reworks Horizon polling: Poll.vue now awaits a required callback prop instead of emitting poll events, and all dashboard/list screens pass refresh methods through it with immediate polling disabled
  • Adds request cancellation and cleanup across Horizon screens: list requests use AbortController with stale-response guards, unmount hooks abort requests and dispose Bootstrap modals and Chart instances, and failed retry/monitoring requests show alerts instead of mutating state
  • Fixes lifecycle bugs: dashboard refreshStatsPeriodically uses Promise.allSettled and only sets ready when all three requests succeed; Telescope's recording toggle and clear-entries handlers await requests before changing state; monitoring tags use upserts in DatabaseEntriesRepository.monitor
  • Raises symfony/console to ^8.1.10 in all package composer.json files and formats the frontend codebase with the Vite+ formatter
  • Risk: the batch-preview route bindings in job.vue, failedJobs/job.vue, and the failure-status v-if in batches/index.vue contain invalid object-expression syntax that may break Vue template compilation

Macroscope summarized 2e6d3f2.

Apply the shared formatter conventions to frontend files whose changes are entirely formatting. Preserve their runtime behavior, upstream names, comments and structure.

Keep this mechanical pass separate so Git blame can ignore it without hiding the dashboard fixes or tooling changes that follow. Files that also require functional changes stay with their corresponding changes.
Bring Horizon, Telescope, the exception renderer, Workbench, Wayfinder and the AI workbench into one pnpm workspace with a shared dependency catalog and lockfile. Keep application skeletons independent and preserve package-local build outputs for Composer distribution.

Pin Vite+ and its matching core and Vitest versions, declare direct dependencies, retain distinct supported Tailwind majors, and remove superseded npm locks and policy files. Preserve the release-age policy and explicitly allow only the required dependency build script.

Use native Vite+ formatting, linting, type checking, test projects and task selection. Generate Wayfinder fixtures before quality checks so the commands work on a fresh installation, and keep cached-route testing in its owning package. Validate frozen installs, all member builds, test discovery and generated TypeScript output.
Move existing Telescope and Wayfinder tests to the bundled Vite+ test APIs while preserving their behavioral assertions. Express negative generated-route argument checks through expectTypeOf and retain the separate generated-output compiler check.

Give Wayfinder test builds isolated temporary directories with cleanup instead of a shared fixed path. Apply the shared formatter to these test files as part of their runner migration. Normal and cached route tests, generated TypeScript checks and the complete JavaScript suite pass.
Use the shared test runner and formatter while retaining the classic-script SDK and its public browser API. Mark asynchronous dispatches whose handlers already own response and error reporting with void, and remove an unused catch binding.

Regenerate the Terser output and verify the browser SDK tests against both source and minified distributions. Keep minification explicit rather than introducing a bundler wrapper or changing how applications load the SDK.
Calculate the inclusive starting index once for tagged failed jobs and use it for both tag selection and returned row indices. Preserve the upstream zero cursor alias so initial requests and later pages agree about their position.

Declare getJobs indexFrom as an integer in the repository contract and implementation, matching the existing strictly typed indexJobs call and its callers. Cover absent, zero, initial and next-page cursors in the controller regression test. Targeted formatting, static analysis and Horizon PHP tests pass.
Make Poll await an explicit callback, prevent overlapping ticks, report failures and release its busy state after settlement. Retain the existing polling intervals and visibility behavior, with focused overlap and recovery coverage.

Release Alert modal listeners, timers and instances on unmount, and fix its accessible label. Keep Chart.js instances non-reactive so animation cleanup sees the original instance and destroy charts when their component is removed.

Key the root view by route path to refresh resource screens while retaining query-only updates. Use package-based Bootstrap Sass with the existing light and dark themes, disable unused Bootstrap color-mode generation, and remove obsolete transition styles and script attributes. Verify modal and chart lifecycles against real browser assets.
Return every polling request to Poll and wait for all dashboard requests to settle before reporting failures. List screens cancel superseded reads and reads owned by an unmounted screen, skip refreshes during user loads, and ignore late canceled responses. Remove duplicate initial loads and redundant route watchers.

Reset failed-job pagination when searching, encode search through Axios parameters, and use after-index cursors consistently. Clear search timers on unmount. Release retry state after failures and explain unconfirmed retries; retain the success cooldown while leaving refreshes to existing polling.

Update monitoring tags only after successful requests, preserve newer drafts and avoid duplicate displayed tags. Handle both numeric and DateInterval delayed-job values. Add focused regression coverage for request settlement, list navigation, cursor boundaries, retries and monitoring behavior; verify the screens using real compiled assets.
Update recording state only after the toggle succeeds, prevent overlapping toggle requests and release the pending state on failure. Report changes that could not be confirmed and reload cleared entries only after success. Exercise these paths through the real mounted application entry.

Wait for the initial monitoring list before enabling additions. Capture submitted tags, preserve newer drafts, deduplicate successful additions and change displayed tags only after successful mutations. Report failed additions and deletions through the existing alert.

Replace monitoring select-and-insert with one native upsert of unique tags so concurrent requests cannot collide on the tag primary key. All shipped database grammars support upsert; a custom DB::extend connection now needs upsert support in its grammar. Retain strict database errors without an insert fallback. Existing storage coverage and focused dashboard tests pass.
Drop the unused bootstrap import and empty module from the authentication frontend. Keep Alpine initialization in its existing entry and preserve the Workbench asset publication contract. The workspace build and independent application browser check pass.
Commit the dashboard, exception renderer and Workbench outputs generated from the shared workspace and reviewed source changes. Replace the obsolete Workbench chunk and update its manifest while preserving all PHP-consumed filenames and inline classic-script behavior.

Verify repeat builds produce identical output, exercise the distributed assets in browser and exported-application checks, and compare compressed bundle sizes. Composer installations continue to receive ready-to-use assets without requiring Node or access to the monorepo catalog. AI workbench build output remains untracked.
Replace the separate frontend installations with a pinned setup-vp action and one frozen workspace install. Run shared source checks, builds, JavaScript tests, cached Wayfinder tests and generated-output type checking sequentially. Trust the mounted checkout before container Git commands.

Fail with affected filenames and contributor instructions when distributed outputs differ or new chunks are untracked. CI verifies committed assets without publishing them or making commits.

Add weekly Dependabot updates for the root catalog and independent skeleton, preserve the seven-day version-update cooldown, and group coupled Vite+ toolchain updates. Retain the existing GitHub Actions updates and independent skeleton installation workflow.
Document native Vite+ installation, quality checks, tests, builds and dependency updates from the components workspace. Explain the independent skeleton boundary and how contributors work on frontend source while maintainers regenerate distributed assets before merge.

Record the approved formatter adaptation for maintained ports and the formatting-only commit in the Git blame ignore file. Describe local blame configuration and preserve upstream structure and naming as the maintenance reference.

Update the AI workbench instructions and active plan to match the implemented commands and verified behavior. Keep post-merge dependency graph verification and upstream-sync guidance updates explicit until publishing is authorized.
@coderabbitai

coderabbitai Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Important

Review skipped

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

Run configuration

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

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

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

@binaryfire

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review skipped: 174 files exceed the limit of 100.

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.

@binaryfire

Copy link
Copy Markdown
Member Author

@cubic-dev-ai review

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 28, 2026

Copy link
Copy Markdown

@cubic-dev-ai review

@binaryfire cubic can't start this review because your workspace has reached its free monthly review limit. cubic has reviewed 123,074 of the 120,000 allowed lines of code this month. Reviews resume on 10 November 2026 (in 13 days). Paid plans include much higher monthly review limits. Upgrade now to resume reviews.

To help optimise your usage, you can tune cubic to get the most out of your usage limits:

Learn more →

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Consolidate frontend tooling and harden dashboard request lifecycles

✨ Enhancement 🐞 Bug fix 🧪 Tests ⚙️ Configuration changes 📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Unify maintained frontends under a Vite+/pnpm workspace while preserving independently installable
 application skeletons.
• Prevent overlapping, stale, and unconfirmed dashboard requests; clean up timers, modals, and
 charts.
• Centralize JavaScript checks and builds, and verify committed assets in CI.
Diagram

graph TD
  W["Workspace catalog"] --> V["Vite+ tasks"] --> P["Package builds"] --> A["Committed assets"] --> C["CI verification"]
  V --> T["Dashboard tests"] --> C
  H["Horizon UI"] --> R["Request lifecycles"]
  S["Telescope UI"] --> R
  R --> T
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Keep package-local toolchains
  • ➕ Preserves independent frontend installs and reduces migration scope.
  • ➖ Retains duplicated lockfiles, divergent dependencies, and multiple CI build paths.
2. Move dashboards to shared request composables
  • ➕ Could centralize cancellation and pending-state rules.
  • ➖ Requires a broader Options API refactor and increases migration risk.

Recommendation: Use the shared workspace with package-local builds and targeted lifecycle fixes. It addresses tooling drift without imposing a root Node installation on Composer consumers or combining this migration with a dashboard rewrite.

Files changed (170) +10013 / -3520

Bug fix (23) +1315 / -847
base.jsAdd a shared Horizon error alert helper +10/-1

Add a shared Horizon error alert helper

• Provides a persistent error message for operations whose results cannot be confirmed.

src/horizon/resources/js/base.js

Alert.vueDispose Horizon alert modals on unmount +38/-52

Dispose Horizon alert modals on unmount

• Binds the modal to its component element and removes its listener, timer, and Bootstrap instance during teardown.

src/horizon/resources/js/components/Alert.vue

LineChart.vueKeep Chart.js instances non-reactive +60/-52

Keep Chart.js instances non-reactive

• Marks chart instances raw and destroys them on unmount so animation cleanup uses the original instance.

src/horizon/resources/js/components/LineChart.vue

Poll.vueAwait Horizon polling callbacks +23/-22

Await Horizon polling callbacks

• Uses a callback prop and pending guard to prevent overlapping ticks and release the guard after failures.

src/horizon/resources/js/components/Poll.vue

index.vueCancel stale batch-list requests +131/-69

Cancel stale batch-list requests

• Aborts superseded and unmounted reads, avoids refreshes during user loads, and clears the search timer.

src/horizon/resources/js/screens/batches/index.vue

preview.vueAlign batch preview request behavior +85/-54

Align batch preview request behavior

• Updates preview request handling and component formatting for the revised dashboard lifecycle.

src/horizon/resources/js/screens/batches/preview.vue

dashboard.vueWait for all dashboard statistics requests +191/-107

Wait for all dashboard statistics requests

• Uses settled results before completing a refresh and connects the dashboard to callback-based polling.

src/horizon/resources/js/screens/dashboard.vue

index.vueStabilize failed-job search and retries +159/-111

Stabilize failed-job search and retries

• Cancels stale reads, resets search pagination, encodes query parameters, and clears retry state with an error when confirmation fails.

src/horizon/resources/js/screens/failedJobs/index.vue

job.vueReport unconfirmed failed-job retries +128/-76

Report unconfirmed failed-job retries

• Releases the detail screen's pending state and displays an error when a retry request fails.

src/horizon/resources/js/screens/failedJobs/job.vue

index.vueConnect metrics polling to callbacks +17/-8

Connect metrics polling to callbacks

• Makes metrics refresh participate in the awaited polling lifecycle.

src/horizon/resources/js/screens/metrics/index.vue

index.vueConfirm monitoring changes before updating tags +98/-66

Confirm monitoring changes before updating tags

• Updates tags after successful requests, preserves newer input, reports failures, and disposes the modal on unmount.

src/horizon/resources/js/screens/monitoring/index.vue

job-row.vueHandle monitored-job actions safely +37/-16

Handle monitored-job actions safely

• Updates action handling and failure feedback for monitored job rows.

src/horizon/resources/js/screens/monitoring/job-row.vue

tag-jobs.vueCancel stale monitored-tag job reads +81/-54

Cancel stale monitored-tag job reads

• Prevents superseded or unmounted requests from updating the tag-job list.

src/horizon/resources/js/screens/monitoring/tag-jobs.vue

tag.vueAwait monitored-tag refreshes +15/-6

Await monitored-tag refreshes

• Connects tag refreshes to the callback-based polling lifecycle.

src/horizon/resources/js/screens/monitoring/tag.vue

index.vueCancel stale recent-job reads +83/-55

Cancel stale recent-job reads

• Aborts superseded requests and skips background refreshes while user-driven loads are pending.

src/horizon/resources/js/screens/recentJobs/index.vue

job-row.vueAlign recent-job row behavior +30/-18

Align recent-job row behavior

• Updates row actions for the revised request lifecycle and shared formatting.

src/horizon/resources/js/screens/recentJobs/job-row.vue

job.vueAlign recent-job detail behavior +41/-34

Align recent-job detail behavior

• Adjusts detail-screen request handling and component formatting.

src/horizon/resources/js/screens/recentJobs/job.vue

JobRepository.phpType the job pagination offset +1/-1

Type the job pagination offset

• Aligns the repository contract with the integer starting index used by pagination.

src/horizon/src/Contracts/JobRepository.php

FailedJobsController.phpUnify tagged failed-job starting indices +3/-3

Unify tagged failed-job starting indices

• Passes the same calculated starting index to tag selection and returned job pagination.

src/horizon/src/Http/Controllers/FailedJobsController.php

RedisJobRepository.phpType the Redis job starting index +1/-1

Type the Redis job starting index

• Requires an integer pagination offset to match the controller and repository contract.

src/horizon/src/Repositories/RedisJobRepository.php

app.jsConfirm Telescope recording and clearing actions +26/-5

Confirm Telescope recording and clearing actions

• Prevents overlapping recording toggles and changes state or reloads entries only after successful responses.

src/telescope/resources/js/app.js

index.vueApply monitored-tag changes after success +52/-34

Apply monitored-tag changes after success

• Waits for add and remove requests before changing displayed tags, preserves newer drafts, and reports failures.

src/telescope/resources/js/screens/monitoring/index.vue

DatabaseEntriesRepository.phpUpsert monitored tags atomically +5/-2

Upsert monitored tags atomically

• Replaces read-then-insert with a native upsert to avoid duplicate-key failures under concurrent requests.

src/telescope/src/Storage/DatabaseEntriesRepository.php

Refactor (55) +1229 / -1269
submission-cleanup.cjsFormat submission cleanup automation +113/-50

Format submission cleanup automation

• Applies shared JavaScript formatting to the existing issue and draft-PR cleanup logic.

.github/scripts/submission-cleanup.cjs

attachment.jsxFormat attachment component +138/-165

Format attachment component

• Applies shared formatting without changing attachment behavior.

dogfood/ai/workbench/resources/js/components/ui/attachment.jsx

bubble.jsxFormat bubble component +77/-99

Format bubble component

• Applies shared formatting without changing bubble behavior.

dogfood/ai/workbench/resources/js/components/ui/bubble.jsx

button.jsxFormat button component +45/-52

Format button component

• Applies shared formatting without changing button behavior.

dogfood/ai/workbench/resources/js/components/ui/button.jsx

input.jsxFormat input component +17/-20

Format input component

• Applies shared formatting without changing input behavior.

dogfood/ai/workbench/resources/js/components/ui/input.jsx

marker.jsxFormat marker component +46/-54

Format marker component

• Applies shared formatting without changing marker behavior.

dogfood/ai/workbench/resources/js/components/ui/marker.jsx

message-scroller.jsxFormat message scroller +86/-104

Format message scroller

• Applies shared formatting without changing scrolling behavior.

dogfood/ai/workbench/resources/js/components/ui/message-scroller.jsx

message.jsxFormat message component +61/-87

Format message component

• Applies shared formatting without changing message behavior.

dogfood/ai/workbench/resources/js/components/ui/message.jsx

Chat.jsxFormat AI chat page +2/-8

Format AI chat page

• Aligns the demo chat page with workspace formatting.

dogfood/ai/workbench/resources/js/pages/Chat.jsx

scripts.jsAlign renderer build script formatting +1/-1

Align renderer build script formatting

• Adjusts the renderer script for the shared frontend checks.

src/foundation/resources/exceptions/renderer/scripts.js

SchemeToggler.vueFormat theme toggler +54/-28

Format theme toggler

• Applies shared formatting while retaining the system, light, and dark theme choices.

src/horizon/resources/js/components/SchemeToggler.vue

Stacktrace.vueFormat Horizon stacktrace +15/-13

Format Horizon stacktrace

• Aligns the component with shared formatting conventions.

src/horizon/resources/js/components/Stacktrace.vue

jobs.vueFormat job metrics screen +29/-29

Format job metrics screen

• Aligns the metrics component with shared frontend formatting.

src/horizon/resources/js/screens/metrics/jobs.vue

preview.vueFormat metrics preview +52/-37

Format metrics preview

• Formats chart-data preparation and the package-local metric preview.

src/horizon/resources/js/screens/metrics/preview.vue

queues.vueFormat queue metrics screen +29/-29

Format queue metrics screen

• Aligns the metrics component with shared frontend formatting.

src/horizon/resources/js/screens/metrics/queues.vue

default.cssFormat default mail theme +6/-3

Format default mail theme

• Reflows CSS declarations without changing the mail theme's intended appearance.

src/mail/resources/views/html/themes/default.css

mcp-sdk.jsFormat MCP browser SDK +16/-48

Format MCP browser SDK

• Applies shared JavaScript formatting while preserving SDK behavior.

src/mcp/resources/js/mcp-sdk.js

base.jsFormat Telescope request helper +1/-1

Format Telescope request helper

• Aligns existing retry feedback with shared formatting.

src/telescope/resources/js/base.js

Alert.vueAlign Telescope alert component +9/-15

Align Telescope alert component

• Formats modal handling without changing the dashboard's alert design.

src/telescope/resources/js/components/Alert.vue

CopyClipboard.vueFormat clipboard component +7/-7

Format clipboard component

• Aligns clipboard UI code with shared formatting.

src/telescope/resources/js/components/CopyClipboard.vue

ExceptionCodePreview.vueFormat exception code preview +4/-4

Format exception code preview

• Aligns exception-preview markup and script with shared formatting.

src/telescope/resources/js/components/ExceptionCodePreview.vue

IndexScreen.vueFormat reusable resource index +109/-98

Format reusable resource index

• Formats the reusable index and its existing cancellation, pagination, and polling paths.

src/telescope/resources/js/components/IndexScreen.vue

PreviewScreen.vueFormat reusable resource preview +33/-39

Format reusable resource preview

• Aligns preview loading and lifecycle code with shared formatting.

src/telescope/resources/js/components/PreviewScreen.vue

RelatedEntries.vueFormat related-entry tabs +76/-68

Format related-entry tabs

• Applies shared formatting to tab selection and related-entry grouping.

src/telescope/resources/js/components/RelatedEntries.vue

Stacktrace.vueFormat Telescope stacktrace +5/-5

Format Telescope stacktrace

• Aligns the component with shared formatting.

src/telescope/resources/js/components/Stacktrace.vue

preview.vueFormat batch preview +2/-2

Format batch preview

• Aligns the resource preview with shared formatting.

src/telescope/resources/js/screens/batches/preview.vue

index.vueFormat cache index +2/-4

Format cache index

• Aligns the resource index with shared formatting.

src/telescope/resources/js/screens/cache/index.vue

preview.vueFormat cache preview +7/-8

Format cache preview

• Aligns the resource preview with shared formatting.

src/telescope/resources/js/screens/cache/preview.vue

index.vueFormat client-request index +3/-5

Format client-request index

• Aligns the resource index with shared formatting.

src/telescope/resources/js/screens/client-requests/index.vue

preview.vueFormat client-request preview +4/-6

Format client-request preview

• Aligns the resource preview with shared formatting.

src/telescope/resources/js/screens/client-requests/preview.vue

preview.vueFormat command preview +4/-4

Format command preview

• Aligns the resource preview with shared formatting.

src/telescope/resources/js/screens/commands/preview.vue

index.vueFormat dumps polling screen +47/-45

Format dumps polling screen

• Formats the existing abortable loading and repeated dump-check workflow.

src/telescope/resources/js/screens/dumps/index.vue

preview.vueFormat event preview +4/-4

Format event preview

• Aligns the resource preview with shared formatting.

src/telescope/resources/js/screens/events/preview.vue

preview.vueFormat exception preview +20/-16

Format exception preview

• Aligns exception detail rendering with shared formatting.

src/telescope/resources/js/screens/exceptions/preview.vue

index.vueFormat gate index +3/-5

Format gate index

• Aligns the resource index with shared formatting.

src/telescope/resources/js/screens/gates/index.vue

preview.vueFormat gate preview +4/-7

Format gate preview

• Aligns the resource preview with shared formatting.

src/telescope/resources/js/screens/gates/preview.vue

index.vueFormat Telescope jobs index +2/-4

Format Telescope jobs index

• Aligns the resource index with shared formatting.

src/telescope/resources/js/screens/jobs/index.vue

preview.vueFormat Telescope job preview +11/-11

Format Telescope job preview

• Aligns the resource preview with shared formatting.

src/telescope/resources/js/screens/jobs/preview.vue

index.vueFormat log index +2/-4

Format log index

• Aligns the resource index with shared formatting.

src/telescope/resources/js/screens/logs/index.vue

preview.vueFormat log preview +9/-8

Format log preview

• Aligns the resource preview with shared formatting.

src/telescope/resources/js/screens/logs/preview.vue

index.vueFormat mail index +10/-8

Format mail index

• Aligns the resource index with shared formatting.

src/telescope/resources/js/screens/mail/index.vue

preview.vueFormat mail preview +10/-7

Format mail preview

• Aligns mail detail rendering with shared formatting.

src/telescope/resources/js/screens/mail/preview.vue

index.vueFormat model index +2/-4

Format model index

• Aligns the resource index with shared formatting.

src/telescope/resources/js/screens/models/index.vue

preview.vueFormat model preview +3/-6

Format model preview

• Aligns the resource preview with shared formatting.

src/telescope/resources/js/screens/models/preview.vue

preview.vueFormat notification preview +2/-2

Format notification preview

• Aligns the resource preview with shared formatting.

src/telescope/resources/js/screens/notifications/preview.vue

preview.vueFormat query preview +5/-3

Format query preview

• Aligns the resource preview with shared formatting.

src/telescope/resources/js/screens/queries/preview.vue

preview.vueFormat Redis preview +2/-2

Format Redis preview

• Aligns the resource preview with shared formatting.

src/telescope/resources/js/screens/redis/preview.vue

index.vueFormat request index +2/-4

Format request index

• Aligns the resource index with shared formatting.

src/telescope/resources/js/screens/requests/index.vue

preview.vueFormat request preview +4/-6

Format request preview

• Aligns the resource preview with shared formatting.

src/telescope/resources/js/screens/requests/preview.vue

preview.vueFormat Reverb preview +1/-1

Format Reverb preview

• Aligns the resource preview with shared formatting.

src/telescope/resources/js/screens/reverb/preview.vue

preview.vueFormat schedule preview +8/-6

Format schedule preview

• Aligns the resource preview with shared formatting.

src/telescope/resources/js/screens/schedule/preview.vue

preview.vueFormat view preview +4/-7

Format view preview

• Aligns the resource preview with shared formatting.

src/telescope/resources/js/screens/views/preview.vue

styles.scssAlign Telescope stylesheet +2/-2

Align Telescope stylesheet

• Formats stylesheet declarations for the consolidated toolchain.

src/telescope/resources/sass/styles.scss

wayfinder.tsFormat Wayfinder runtime +11/-8

Format Wayfinder runtime

• Applies shared formatting without changing generated route behavior.

src/wayfinder/resources/js/wayfinder.ts

build.tsFormat Wayfinder test builder +8/-6

Format Wayfinder test builder

• Aligns fixture-building test utilities with shared formatting.

src/wayfinder/tests/build.ts

Tests (53) +1024 / -219
submission-cleanup.test.cjsFormat submission cleanup tests +110/-42

Format submission cleanup tests

• Applies shared formatting to the existing automation tests.

.github/scripts/submission-cleanup.test.cjs

Alert.test.jsTest Horizon modal cleanup +105/-0

Test Horizon modal cleanup

• Covers alert modal ownership, listeners, timers, and unmount behavior.

src/horizon/resources/js/components/Alert.test.js

Poll.test.jsTest asynchronous polling +35/-0

Test asynchronous polling

• Verifies that polling waits for callbacks and does not overlap requests.

src/horizon/resources/js/components/Poll.test.js

Lists.test.jsTest Horizon list request ownership +140/-0

Test Horizon list request ownership

• Covers cancellation, skipped refreshes, pagination, and cleanup for list screens.

src/horizon/resources/js/screens/Lists.test.js

Retry.test.jsTest failed retry handling +50/-0

Test failed retry handling

• Checks that failed retries release pending UI state and report an unconfirmed outcome.

src/horizon/resources/js/screens/Retry.test.js

dashboard.test.jsTest complete dashboard refreshes +34/-0

Test complete dashboard refreshes

• Verifies refresh waits for every request to settle, including when one fails.

src/horizon/resources/js/screens/dashboard.test.js

index.test.jsTest Horizon monitoring requests +108/-0

Test Horizon monitoring requests

• Covers successful tag updates, preserved drafts, failures, and modal cleanup.

src/horizon/resources/js/screens/monitoring/index.test.js

job-row.test.jsTest monitored-job row actions +36/-0

Test monitored-job row actions

• Covers request and pending-state behavior for monitoring row actions.

src/horizon/resources/js/screens/monitoring/job-row.test.js

app.test.jsTest Telescope root actions +87/-0

Test Telescope root actions

• Covers recording toggle overlap, failure feedback, and clearing entries only after success.

src/telescope/resources/js/app.test.js

Alert.test.jsAlign Telescope alert tests +9/-3

Align Telescope alert tests

• Updates alert assertions and formatting for the shared test project.

src/telescope/resources/js/components/Alert.test.js

CopyClipboard.test.jsFormat clipboard tests +1/-1

Format clipboard tests

• Aligns existing clipboard assertions with shared formatting.

src/telescope/resources/js/components/CopyClipboard.test.js

ExceptionCodePreview.test.jsFormat exception preview tests +2/-2

Format exception preview tests

• Aligns existing exception-preview assertions with shared formatting.

src/telescope/resources/js/components/ExceptionCodePreview.test.js

IndexScreen.test.jsAlign resource-index lifecycle tests +19/-15

Align resource-index lifecycle tests

• Updates tests for resource navigation, query changes, and existing request cancellation.

src/telescope/resources/js/components/IndexScreen.test.js

PreviewScreen.test.jsExpand resource-preview lifecycle tests +44/-21

Expand resource-preview lifecycle tests

• Exercises preview navigation, pending requests, and cleanup behavior.

src/telescope/resources/js/components/PreviewScreen.test.js

RelatedEntries.test.jsAlign related-entry tests +12/-4

Align related-entry tests

• Formats and adjusts assertions for related-entry rendering.

src/telescope/resources/js/components/RelatedEntries.test.js

routes.test.jsTest resource route remounting +21/-8

Test resource route remounting

• Covers path-change remounts while preserving query-only updates.

src/telescope/resources/js/routes.test.js

preview.test.jsFormat cache preview tests +3/-3

Format cache preview tests

• Aligns existing preview assertions with shared formatting.

src/telescope/resources/js/screens/cache/preview.test.js

index.test.jsFormat dumps index tests +7/-4

Format dumps index tests

• Aligns existing dump-screen assertions with shared formatting.

src/telescope/resources/js/screens/dumps/index.test.js

preview.test.jsFormat mail preview tests +4/-4

Format mail preview tests

• Aligns existing preview assertions with shared formatting.

src/telescope/resources/js/screens/mail/preview.test.js

index.test.jsTest Telescope monitoring confirmations +54/-6

Test Telescope monitoring confirmations

• Covers successful tag changes, failed requests, duplicate prevention, and preserved input drafts.

src/telescope/resources/js/screens/monitoring/index.test.js

preview.test.jsFormat query preview tests +3/-3

Format query preview tests

• Aligns existing preview assertions with shared formatting.

src/telescope/resources/js/screens/queries/preview.test.js

AnonymousMiddleware.test.tsFormat anonymous-middleware test +1/-1

Format anonymous-middleware test

• Aligns the existing test with shared formatting.

src/wayfinder/tests/AnonymousMiddleware.test.ts

AppUrlRootResolution.test.tsFormat application-root tests +17/-11

Format application-root tests

• Reflows URL-root resolution assertions for the shared formatter.

src/wayfinder/tests/AppUrlRootResolution.test.ts

CamelCaseRouteParameter.test.tsFormat camel-case parameter test +1/-1

Format camel-case parameter test

• Aligns the existing test with shared formatting.

src/wayfinder/tests/CamelCaseRouteParameter.test.ts

DefaultParameters.test.tsFormat default-parameter tests +2/-5

Format default-parameter tests

• Aligns existing assertions with shared formatting.

src/wayfinder/tests/DefaultParameters.test.ts

DisallowedMethodNames.test.tsFormat disallowed-method test +1/-1

Format disallowed-method test

• Aligns the existing test with shared formatting.

src/wayfinder/tests/DisallowedMethodNames.test.ts

DomainController.test.tsFormat domain-controller test +1/-1

Format domain-controller test

• Aligns the existing test with shared formatting.

src/wayfinder/tests/DomainController.test.ts

EmptyRoute.test.tsFormat empty-route test +1/-1

Format empty-route test

• Aligns the existing test with shared formatting.

src/wayfinder/tests/EmptyRoute.test.ts

Export.test.tsFormat export test +1/-1

Format export test

• Aligns the existing test with shared formatting.

src/wayfinder/tests/Export.test.ts

GeneratedOutput.test.tsFormat generated-output test +1/-1

Format generated-output test

• Aligns the existing test with shared formatting.

src/wayfinder/tests/GeneratedOutput.test.ts

IdentifierCollisions.test.tsFormat identifier-collision tests +2/-4

Format identifier-collision tests

• Reflows existing assertions for the shared formatter.

src/wayfinder/tests/IdentifierCollisions.test.ts

IndexNamedRoute.test.tsFormat index-route test +1/-1

Format index-route test

• Aligns the existing test with shared formatting.

src/wayfinder/tests/IndexNamedRoute.test.ts

InvokableController.test.tsFormat invokable-controller test +1/-1

Format invokable-controller test

• Aligns the existing test with shared formatting.

src/wayfinder/tests/InvokableController.test.ts

InvokablePlusController.test.tsFormat invokable-plus-controller test +1/-1

Format invokable-plus-controller test

• Aligns the existing test with shared formatting.

src/wayfinder/tests/InvokablePlusController.test.ts

KeyController.test.tsFormat key-controller tests +2/-4

Format key-controller tests

• Reflows existing assertions for the shared formatter.

src/wayfinder/tests/KeyController.test.ts

MethodNameCollision.test.tsFormat method-collision test +1/-1

Format method-collision test

• Aligns the existing test with shared formatting.

src/wayfinder/tests/MethodNameCollision.test.ts

ModelBindingController.test.tsFormat model-binding tests +7/-11

Format model-binding tests

• Reflows existing assertions for the shared formatter.

src/wayfinder/tests/ModelBindingController.test.ts

NamedRoutes.test.tsFormat named-route tests +11/-3

Format named-route tests

• Reflows existing assertions for the shared formatter.

src/wayfinder/tests/NamedRoutes.test.ts

NamedspacedRoute.test.tsFormat namespaced-route test +1/-1

Format namespaced-route test

• Aligns the existing test with shared formatting.

src/wayfinder/tests/NamedspacedRoute.test.ts

NestedController.test.tsFormat nested-controller test +1/-1

Format nested-controller test

• Aligns the existing test with shared formatting.

src/wayfinder/tests/NestedController.test.ts

OptionalController.test.tsFormat optional-controller test +1/-1

Format optional-controller test

• Aligns the existing test with shared formatting.

src/wayfinder/tests/OptionalController.test.ts

ParamaterName.test.tsFormat parameter-name test +1/-1

Format parameter-name test

• Aligns the existing test with shared formatting.

src/wayfinder/tests/ParamaterName.test.ts

PathNameNormalization.test.tsFormat path-normalization test +1/-1

Format path-normalization test

• Aligns the existing test with shared formatting.

src/wayfinder/tests/PathNameNormalization.test.ts

PostController.test.tsFormat POST-controller test +1/-1

Format POST-controller test

• Aligns the existing test with shared formatting.

src/wayfinder/tests/PostController.test.ts

QueryMethod.test.tsFormat query-method tests +5/-2

Format query-method tests

• Reflows existing assertions for the shared formatter.

src/wayfinder/tests/QueryMethod.test.ts

QueryParams.test.tsFormat query-parameter test +1/-1

Format query-parameter test

• Aligns the existing test with shared formatting.

src/wayfinder/tests/QueryParams.test.ts

RepeatedNamespaceController.test.tsFormat repeated-namespace test +1/-1

Format repeated-namespace test

• Aligns the existing test with shared formatting.

src/wayfinder/tests/RepeatedNamespaceController.test.ts

SharedUriController.test.tsFormat shared-URI tests +9/-7

Format shared-URI tests

• Reflows existing assertions for the shared formatter.

src/wayfinder/tests/SharedUriController.test.ts

StorageRoute.test.tsFormat storage-route test +1/-1

Format storage-route test

• Aligns the existing test with shared formatting.

src/wayfinder/tests/StorageRoute.test.ts

TwoRoutesSameAction.test.tsFormat shared-action test +1/-1

Format shared-action test

• Aligns the existing test with shared formatting.

src/wayfinder/tests/TwoRoutesSameAction.test.ts

UrlDefaultsController.test.tsFormat URL-defaults test +1/-1

Format URL-defaults test

• Aligns the existing test with shared formatting.

src/wayfinder/tests/UrlDefaultsController.test.ts

FailedJobsControllerTest.phpTest tagged failed-job pagination +20/-0

Test tagged failed-job pagination

• Adds coverage for the consistent starting index used to select and return tagged jobs.

tests/Horizon/Unit/FailedJobsControllerTest.php

BrowserSdk.test.jsFormat MCP browser SDK tests +43/-34

Format MCP browser SDK tests

• Aligns the SDK test suite with shared JavaScript formatting.

tests/Mcp/BrowserSdk.test.js

Documentation (4) +71 / -144
AGENTS.mdClarify contributor tooling guidance +1/-0

Clarify contributor tooling guidance

• Adds guidance for agents working with the maintained frontend workspace.

AGENTS.md

2026-10-27-telescope-vue3-and-vite-plus.mdRevise frontend migration plan +31/-133

Revise frontend migration plan

• Updates the plan to reflect the shared Vite+ workspace and retained dashboard structure.

docs/plans/2026-10-27-telescope-vue3-and-vite-plus.md

README.mdDocument AI workbench workspace commands +6/-5

Document AI workbench workspace commands

• Replaces standalone frontend instructions with commands appropriate to the root workspace.

dogfood/ai/README.md

contributions.mdDocument frontend contribution workflow +33/-6

Document frontend contribution workflow

• Explains installation, quality commands, dependency updates, and maintainer regeneration of committed assets.

src/docs/contributions.md

Other (35) +6374 / -1041
.git-blame-ignore-revsIgnore mechanical formatting revision +2/-0

Ignore mechanical formatting revision

• Records the formatting-only commit so blame can focus on functional changes.

.git-blame-ignore-revs

dependabot.ymlConfigure workspace dependency updates +21/-0

Configure workspace dependency updates

• Adds update coverage for the shared catalog while retaining separate handling for independent skeletons.

.github/dependabot.yml

tests.ymlConsolidate JavaScript CI +31/-33

Consolidate JavaScript CI

• Replaces separate installs and test jobs with a frozen workspace install, Vite+ checks, builds, tests, and committed-asset verification.

.github/workflows/tests.yml

jsconfig.jsonAlign AI workbench JavaScript configuration +1/-2

Align AI workbench JavaScript configuration

• Adjusts editor configuration for the workspace toolchain.

dogfood/ai/workbench/jsconfig.json

package.jsonEnroll AI workbench in the workspace +8/-7

Enroll AI workbench in the workspace

• Aligns package scripts and dependencies with the shared catalog while retaining its local build.

dogfood/ai/workbench/package.json

vite.config.jsUse the workspace Vite+ configuration API +1/-1

Use the workspace Vite+ configuration API

• Updates the local build configuration to use the shared toolchain.

dogfood/ai/workbench/vite.config.js

package.jsonExpose root Vite+ commands +27/-11

Expose root Vite+ commands

• Adds shared checks, test projects, package builds, and Wayfinder fixture generation; pins the Vite+ dependency through the catalog.

package.json

pnpm-lock.yamlLock the consolidated frontend workspace +6020/-743

Lock the consolidated frontend workspace

• Records dependencies for the newly included packages and pinned shared toolchain in one lockfile.

<a href='https://github.com/hypervel/components/pull/706/files#diff-32824c984905bb02bc7ffcef96a77addd1f1602cff71a11fbbfd...

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Fast tag-removal failures hide their error 🐞 Bug ≡ Correctness
Description
removeTag now returns the delete request and calls alertError() when it fails, but
Alert.confirm() neither waits for nor returns that promise. It calls close() straight away. If
the request fails while the confirmation modal is still fading out (Bootstrap's hide transition,
about 300 ms), the error is written into the same $root.alert state. Because the `<alert
v-if="alert.type"> component stays mounted, the modal's hidden handler then clears type` and
message, so the new "could not confirm the monitoring change" message is wiped before it can be
shown.
Code

src/telescope/resources/js/screens/monitoring/index.vue[R57-67]

+            this.alertConfirm('Are you sure you want to remove this tag?', () => {
+                return axios
+                    .post(Telescope.basePath + '/telescope-api/monitored-tags/delete', { tag })
+                    .then(() => {
+                        this.tags = _.reject(this.tags, (t) => t === tag);
+                    })
+                    .catch(() => {
+                        this.alertError(
+                            'Telescope could not confirm the monitoring change. Reload the page to check the current tags.',
+                        );
+                    });
Evidence
monitoring/index.vue passes a callback to alertConfirm that returns the axios promise and calls
alertError in its .catch. Alert.vue confirm() calls this.confirmationProceed() without
awaiting it and then calls this.close(), which starts the hide transition. When that transition
finishes, hidden() resets $root.alert.type, message and the callbacks. The layout renders a
single `. If the error arrives before hidden` fires, it is set on the still-mounted instance and
then wiped. That instance never calls show() again, so nothing re-displays it.

src/telescope/resources/js/components/Alert.vue[41-69]
src/telescope/resources/views/layout.blade.php[25-30]
src/telescope/resources/js/screens/monitoring/index.vue[56-69]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Telescope's `Alert.confirm()` calls `confirmationProceed()` and closes the modal right away. Callbacks that now return a promise and call `alertError()` on failure, such as monitoring `removeTag`, can have their error wiped. The closing confirmation modal's `hidden` handler resets `$root.alert` after the error has been written to it.
## Fix Focus Areas
- src/telescope/resources/js/components/Alert.vue[63-69]
- src/telescope/resources/js/screens/monitoring/index.vue[56-69]
## Recommended Fix
Make `confirm()` async: `await Promise.resolve(this.confirmationProceed?.())` inside try/finally, then call `this.close()`. Disable the buttons while the callback is pending. Option B: wait for the modal's `hidden.bs.modal` event before running the request or showing the error. Option C: have `hidden()` reset `$root.alert` only if it still holds this instance's confirmation. Make the matching change in Horizon's Alert.vue so the two stay consistent.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can turn on the rule miner and Qodo learns your standards from review history

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread src/telescope/resources/js/screens/monitoring/index.vue
Symfony HTTP Foundation now accepts the cookie name zero. Keep the enum regression test focused on its actual contract: direct strings and enum-backed names must follow native Cookie validation across the supported Symfony versions.

Use only native construction inside the exception probe, then exercise CookieJar outside that catch so assertions cannot be swallowed. Verify the test with HTTP Foundation 8.1.9 and the Cookie suite with 8.1.10 without changing runtime behavior or raising the dependency minimum.
Symfony Console 8.1.10 recognizes built-in named styles regardless of case. Match that behavior when measuring visible text and preserving trailing style tags during grapheme replacement, so uppercase tags do not affect layout or get partially overwritten.

Require Console 8.1.10 in Prompts and the development root, and change only the named-style regex groups. Preserve escape handling, unknown tags and terminal control parsing without adding formatter allocations or runtime version checks.

Extend the existing formatter-parity and trailing-tag tests with mixed-case and uppercase inputs. Both cases fail before their fixes and pass afterward; targeted formatting, Prompts static analysis and the affected suites pass.
Describe the required case-insensitive Prompts handling and native cookie-validation parity exposed by fresh dependency resolution. Keep the active plan aligned with the final design and the remaining PR, CI and post-merge work.
Raise every existing split-package Console requirement to ^8.1.10, matching the development root and Prompts. The repository checks external dependency constraints for exact consistency, so the earlier root and Prompts update also needs to be reflected in the other declarations.

Preserve the shared manifest invariant and all package-specific metadata assertions. No runtime code or new test machinery is needed. The Composer consistency suite, complete package metadata selection and validation of every changed manifest pass. Update the active plan to describe the shared requirement.
@binaryfire
binaryfire merged commit 26454cf into 0.4 Oct 28, 2026
54 checks passed
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.

1 participant