Modern IDE-style UI, code assistance, and streaming output - #80
Merged
Conversation
royteeuwen
force-pushed
the
feature/modern-ui-and-streaming
branch
2 times, most recently
from
June 13, 2026 20:09
76ca186 to
5af6a9d
Compare
Modern UI (new ui.frontend module — Lit + Spectrum Web Components + Monaco, Vite): - IDE-style shell: app bar with primary Run action, resizable editor/output split, tabbed output dock (Result/Log/Trace/Table) with running-time badge and clickable stacktrace frames that jump to the source line, activity rail with History / Scheduled Jobs / Help drawers, status bar with run state, cursor position and shortcut hints (Cmd+Enter run, Cmd+S save, Cmd+K commands) - IDE-grade code assistance backed by new /bin/groovyconsole/assist/* servlets: class dictionary from OSGi bundle wiring (with auto-import), member completion via reflection incl. Groovy metaclass/GDK methods, binding and star-import context, and live compile diagnostics (parse-only, shared shell configuration with execution via the extracted GroovyShellFactory) - Folder-navigable script browser and save dialog that also work on plain Sling - Built into ui.apps at /apps/groovyconsole/spa with stable asset names Routing and configuration: - New defaultUi OSGi property (classic|modern, default classic); /groovyconsole serves the default while the classic/modern selectors always work; both UIs cross-link each other Classic UI modernization: - Replace the AEM-only ExtJS open/save dialogs with Bootstrap modals that also work on plain Sling; drop cq.wcm.edit and cq.shared clientlib dependencies (context path now injected via HTL); delete the obsolete groovyconsole-aem ExtJS dialog definitions - Fix pre-existing NPE in ScheduledJobsServlet on plain Sling and add the permission gate to ServicesListServlet Testing and infrastructure: - New ui.tests module: Playwright end-to-end suite behind -Pui-tests, booting its own Sling feature-model instance; AssistIT integration tests; CI updated
Scripts can now be executed asynchronously (POST /bin/groovyconsole/post with async=true) returning an execution id; output is polled incrementally from the new /bin/groovyconsole/stream endpoint while the script runs. The execution registry buffers output per execution, retains finished executions for ten minutes, and audits results exactly as synchronous runs do. Both UIs consume it: the modern UI shows a live output dock during the run and the classic UI appends to its output panel. Both fall back transparently to synchronous execution against older backends. Backwards compatible: without the async parameter the endpoint behaves exactly as before, keeping external clients such as the IntelliJ AEM Groovy Console plugin working unchanged. Covered by StreamingIT (including a test proving compile-only semantics and partial output before completion) and Playwright specs for both UIs.
- Send Cache-Control: no-store on the stream polling endpoint so responses are never cached by a CDN (AEM as a Cloud Service) - Degrade gracefully in both UIs when polling loses the execution (e.g. the request is routed to another cluster instance): explain that the script keeps running and point to the History panel, instead of reporting a failure - Document the async/stream API contract and the cluster affinity caveat in the README - Gate StreamingIT on actual endpoint readiness instead of only the system health check to avoid a startup race
Manual testing on the AEMaaCS SDK surfaced that browser POSTs were rejected with 403 by the Granite CSRF filter (header-authenticated clients such as curl and the IntelliJ plugin are unaffected): - The modern UI now fetches /libs/granite/csrf/token.json and sends the CSRF-Token header on POST/DELETE requests when running on AEM (skipped on plain Sling) - The classic UI's AEM clientlib declares the granite.csrf.standalone dependency, restoring the automatic token injection previously provided transitively by the removed cq.shared dependency
Extracts the shared Sling feature aggregation and launch configuration into pluginManagement so the existing 'it' profile and a new 'run' profile reuse it without duplication. mvn clean install mvn verify -Prun -pl it.tests # boots Sling on http://localhost:8080 (admin/admin) The run profile launches the same aggregated feature the integration tests use, on a fixed port (override with -Dhttp.port), and blocks in the foreground tailing the instance log; Ctrl+C stops it.
…ceholders - The output dock now selects Log (script output) by default on completion, with Result as a secondary tab — matching the classic console where the log was the primary view. Errors still jump to the Trace tab. - Widen the slide-out drawers (720 -> 960px) and keep timestamp links on one line so History/Scheduled Jobs dates no longer wrap. - Mute sp-textfield placeholders (grey italic) in the scheduler and save dialogs; Spectrum renders them in the text colour by default, making empty fields look pre-filled.
- Change the Default UI OSGi property default from classic to modern, so /groovyconsole serves the modern UI out of the box (classic still reachable via the .classic.html selector). - Document the modern UI, code assistance, streaming output, the run profile and the Default UI setting in the README, and record everything under [Unreleased] in the CHANGELOG.
royteeuwen
force-pushed
the
feature/modern-ui-and-streaming
branch
from
June 13, 2026 20:32
5af6a9d to
4df7a96
Compare
on: [push, pull_request] fired both events for same-repo PR branches, running every commit twice. Restrict push to main and add a concurrency group so only one run happens per PR commit and superseded runs are cancelled.
- Order static imports before regular imports in the new/modified Groovy servlets and models (Groovy rule S8314). - Modernize the classic console.js code added for streaming and the open/save dialogs: const/let over var, optional chaining, globalThis, and a fixed regex character-class escape. - Extract a SEVERITY_ERROR constant for the repeated compile-marker severity. - Suppress S2925 on StreamingIT, where Thread.sleep is intentional remote polling (matching GroovyConsoleServiceIT). Left as-is: the Bootstrap modal role="dialog" attributes (S6819) — Bootstrap 3 modals require the role and a native <dialog> would break their show/hide.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
Adds a modern, IDE-style console UI alongside the classic one, with code assistance and live streaming output, and makes the modern UI the default at
/groovyconsole. The classic UI is modernized to drop its AEM-only dependencies so it also works on plain Sling. All changes are backwards compatible for existing API clients (e.g. the IntelliJ plugin).Built on top of the Groovy 5 / Java 11 baseline already on
main.What's included
Modern UI (
ui.frontend— Lit + Spectrum Web Components + Monaco, Vite)ui.appsat/apps/groovyconsole/spa.Code assistance (
/bin/groovyconsole/assist/*)getService("..."), and live compile diagnostics (parse-only, sharing the execution compiler config via the extractedGroovyShellFactory).Streaming output
POST /bin/groovyconsole/post.json?async=true→{executionId}, pollGET /bin/groovyconsole/stream.json; output streams while the script runs. Both UIs consume it (classic streams into its output panel). Withoutasyncthe endpoint is unchanged, so curl / the IntelliJ plugin keep working.Cache-Control: no-storeon polls, graceful degradation when a poll is routed to another cluster node.Routing & config
modernby default). Both UIs always reachable via.modern.html/.classic.htmlselectors and cross-link each other.Classic UI modernization
cq.wcm.editandcq.sharedclientlib deps (CSRF token now viagranite.csrf.standalone).Fixes
ScheduledJobsServletNPE on plain Sling (no next execution date).Tooling & tests
ui.testsmodule with Playwright e2e;runMaven profile (mvn verify -Prun -pl it.tests) to launch the aggregated feature model for manual testing (shared config viapluginManagement).AssistIT+StreamingITintegration tests.Verification
clean installwith bnd baseline enforced (no skip).defaultUitoggle, assist over AEM APIs).Notes for reviewers
bobi/aem-groovyconsole-plugin) — kept separate, not part of this PR.