feat: integrate cdk explorer branch - #1748
Draft
megha-narayanan wants to merge 41 commits into
Draft
Conversation
Basic scaffolding for new packages to be implemented: a core functionality library, the lsp server, and the web explorer. ### Checklist - [ ] This change contains a major version upgrade for a dependency and I confirm all breaking changes are addressed - Release notes for the new version: --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license
Refactor: put LSP skeleton in a unique branch from web explorer - [ ] This change contains a major version upgrade for a dependency and I confirm all breaking changes are addressed - Release notes for the new version: --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license --------- Fixes # ### Checklist - [ ] This change contains a major version upgrade for a dependency and I confirm all breaking changes are addressed - Release notes for the new version: --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license --------- Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
- Adds a minimal Express web server in `@aws-cdk/cdk-explorer` with a `/api/health` endpoint - Wires up `cdk explore` as a CLI subcommand that starts the server and blocks until SIGINT/SIGTERM - Port behavior: auto-increments from 4200 if default is taken; throws if an explicit -`-port` is unavailable Fixes # - [ ] This change contains a major version upgrade for a dependency and I confirm all breaking changes are addressed - Release notes for the new version: --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license --------- Fixes # ### Checklist - [ ] This change contains a major version upgrade for a dependency and I confirm all breaking changes are addressed - Release notes for the new version: --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license --------- Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…r-remerge # Conflicts: # packages/aws-cdk/THIRD_PARTY_LICENSES
- Adds an assembly reader that joins `cdk.out/`'s `tree.json` with each stack's manifest metadata into a `ConstructNode` tree carrying `logicalId`, CFN type, and source location. - LSP publishes CDK validation violations as `Diagnostic`s anchored to the construct's TypeScript source line, with rule-level severity. - LSP serves `CodeLens` entries above each construct creation site summarising the CFN resources it produces. - Source resolution covers `.ts` and `.js` (with sibling `.js.map`); non-TS apps degrade gracefully (no crash, no source-linked features). Fixes # ### Checklist - [ ] This change contains a major version upgrade for a dependency and I confirm all breaking changes are addressed - Release notes for the new version: --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license
Builds on #1592, which surfaced display-only CodeLens entries for the CFN resources each construct produces. This PR makes them **clickable**. Selecting a lens jumps to the resource's definition in the synthesized CloudFormation template. Features: - **Clickable navigation** — each lens carries an `openResource` command that opens the resource's template file at its logical-ID line. - **Multi-resource picker** — constructs producing several resources show a QuickPick; single-resource constructs open directly. - **Positional `templateFile` resolution (cloud-assembly-api)** — `buildConstructTree` threads the owning template through the tree, switching at NestedStack boundaries. - **Clearer titles** — `Creates AWS::S3::Bucket`, or `Creates 3 resources: AWS::S3::Bucket, AWS::S3::BucketPolicy, AWS::KMS::Key`. ### Checklist - [ ] This change contains a major version upgrade for a dependency and I confirm all breaking changes are addressed - Release notes for the new version: --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license --------- Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
- Computes character ranges for CloudFormation resource blocks in
synthesized templates and uses them for navigation in both directions:
-
- CodeLens "go to" now selects the whole resource block (was a
zero-width cursor).
- New go-to-definition from a synthesized template back to the
construct's source.
A note on the JSON parser dependency Computing character ranges needs a
position-aware JSON parser, since JSON.parse discards offsets. The
natural choice is jsonc-parser (what the VS Code JSON language service
uses). We could not use it here: its UMD entry loads internal modules
through a parameter-shadowed require("./impl/...") that esbuild (used by
node-backpack to bundle the CLI) cannot statically trace, so the bundled
`cdk/cdk-assets` binaries fail with `Cannot find module
'./impl/format'`. Known, still-open:
[microsoft/node-jsonc-parser#57](microsoft/node-jsonc-parser#57),
[evanw/esbuild#1619](evanw/esbuild#1619). Its
ESM build bundles fine, but the esbuild mainFields workaround isn't
exposed by node-backpack, and importing the ESM build directly breaks
our CommonJS tests; marking it external isn't appropriate for a
self-contained CLI. So we use
[json-source-map](https://www.npmjs.com/package/json-source-map), a
single-file CommonJS module that bundles cleanly.
### Checklist
- [ ] This change contains a major version upgrade for a dependency and
I confirm all breaking changes are addressed
- Release notes for the new version:
---
By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache-2.0 license
The LSP currently reads `cdk.out` once at startup and never refreshes. After this PR, any rewrite of `cdk.out` refreshes the editor's diagnostics and CodeLenses automatically. * New `lib/core/assembly-watcher.ts`: a chokidar-backed watcher with a debounced 200ms `onChange`, filtered to `manifest.json`, `tree.json`, `validation-report.json`. RWLock marker files (`synth.lock`, `read.<pid>.<n>.lock`) are excluded. Throws from `onChange` route through `onError` rather than leaking from the timer. Lives in `lib/core/` so the web explorer can reuse it. * `refreshFromAssembly` is now the single fan-out for new assembly data: rebuild `cachedIndex`, publish empty diagnostics for URIs that no longer have violations (clearing resolved squiggles), republish current diagnostics, and send `workspace/codeLens/refresh` (gated on `workspace.codeLens.refreshSupport`). * When the validation report fails to load, last-good diagnostics are preserved, matching the existing contract for `'error'` and `'not-found'` reads. * Watcher started in `onInitialized` after the initial refresh, closed in `onShutdown`. Fixes # ### Checklist - [ ] This change contains a major version upgrade for a dependency and I confirm all breaking changes are addressed - Release notes for the new version: --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license
Builds the `cdk explore` web explorer UI, with a React + Cloudscape single-page app is served by the existing Express server, alongside file-serving API endpoints. - **API** (`lib/web/`): `GET /api/health`, `GET /api/files?dir=`,`GET /api/file?path=`, - **SPA** (`frontend/`): Cloudscape `ContentLayout` with four regions. The two center/right panes are functional server-backed file viewers (browse + view). Header shows a "last updated" placeholder. - **Build**: `frontend/` is compiled by esbuild (separate `tsconfig.frontend.json`, kept off the Node `tsc` path) in `post-compile`, then embedded into `web-assets.generated.json` and served from memory so it travels in the bundled CLI. ### Checklist - [ ] This change contains a major version upgrade for a dependency and I confirm all breaking changes are addressed - Release notes for the new version: --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license --------- Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…rer-merge-cdk-lsp
The LSP followed source/template paths from the cloud assembly (stack-trace frames, source maps, template paths) with only an extension allow-list. If cdk.out is tampered with, a crafted path like `../../../etc/passwd.js` could be read or surfaced as a nav target. Adds a symlink-aware `isWithinRoot` and gates every read: source paths against the project dir, `templateFile` against the assembly dir. Out-of-root paths are dropped as not-navigable (same as non-TS apps). No change for valid assemblies. Fixes # ### Checklist - [ ] This change contains a major version upgrade for a dependency and I confirm all breaking changes are addressed - Release notes for the new version: --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license
Convert the two synchronous template reads on the LSP request paths (onDefinition and the CodeLens provider) to fs.promises, continuing the async direction from #1631. resourceTarget, codeLensesForFile, and commandFor are now async and read sequentially, so the number of concurrent reads never grows with app size. The LspHandlers interface widens onCodeLens and onDefinition to return Promises; the connection wiring passes the Promise through unchanged. readAssembly and the source-map reads stay synchronous: they run at startup and on watch events, not per request, and convert-source-map takes a synchronous reader. Fixes # ### Checklist - [ ] This change contains a major version upgrade for a dependency and I confirm all breaking changes are addressed - Release notes for the new version: --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license
…rer-merge-cdk-lsp
Add utilities to source resolver to parse jsii host-language creation-stack frames for Python, and drop the TypeScript-only diagnostics gate. Go-to-definition (source → template, and reverse) and policy-violation diagnostics now work for Python apps, not just TypeScript. Requires synthing with `JSII_HOST_STACK_TRACES=1` (opt-in; jsii 1.137+ / aws-cdk-lib 2.260+). Auto-enabling it for LSP-triggered synth is a follow-up. Java support separated into new PR due to FQN path parsing complexities. Example: <img width="819" height="568" alt="Screenshot 2026-06-25 at 1 30 10 PM" src="https://github.com/user-attachments/assets/c20a136e-656f-47b2-a15f-71a585645ba0" /> ### Checklist - [ ] This change contains a major version upgrade for a dependency and I confirm all breaking changes are addressed - Release notes for the new version: --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license --------- Co-authored-by: Otavio Macedo <288203+otaviomacedo@users.noreply.github.com>
# Conflicts: # packages/@aws-cdk/integ-runner/THIRD_PARTY_LICENSES # packages/aws-cdk/THIRD_PARTY_LICENSES # packages/cdk-assets/THIRD_PARTY_LICENSES # yarn.lock
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Adds manual synth and auto-synth-on-save to the CDK LSP. The cdk.out watcher (landed in #1630) handles all diagnostics/lens refreshes -- these commands just add new ways to produce a fresh assembly. Features: ↻ Synth now CodeLens at the top of any CDK source file (only when auto-synth is off) ▶ Enable auto-synth / ⏹ Disable auto-synth toggle Auto-synth starts disabled When auto-synth is on, saving any non-ignored file in the project triggers a synth All feedback/output goes to the Output panel, no popups Design decisions (the important ones): Concurrent synths are supressed: if a save fires during a slow synth, that save is skipped. The next save picks it up. cdk.json is read once at startup. Changing it requires an LSP restart. The toggle/synth lenses only appear on files that already have L1 resource lenses. Files with no CDK resources see nothing. Toggle state resets to disabled on LSP restart (not persisted). NOTE: One thing not in this PR (but must land before prod) is a workspace trust gate. We should verify with the user that they trust this workspace before running any synth. I may need to set up some way to preserve this between sessions. Open questions / things I need some feedback on: - Is "auto-synth" the right name? Alternatives: "synth on save", "live synth"? - Where should the toggle live? Line 0 of a CDK file works for LSP-only, but it's only visible when you're in a file with constructs. Status bar item would be better UX but needs a client extension. Is there a better alternative? - Should synth failures (app compile errors) be more visible than the Output panel? A diagnostic on the first line of the failing file, for example? - If the app has context lookups and no cached cdk.context.json, synth fails with an auth/context error. Should the error message detect this and suggest running cdk synth in terminal first? <img width="809" height="161" alt="Screenshot 2026-06-16 at 3 41 01 PM" src="https://github.com/user-attachments/assets/b542927c-0206-462f-8464-2c43f19bbe0b" /> <img width="771" height="166" alt="Screenshot 2026-06-16 at 3 41 10 PM" src="https://github.com/user-attachments/assets/52695e76-2e1d-4fc8-ada7-d1ce338512cf" /> ### Checklist - [ ] This change contains a major version upgrade for a dependency and I confirm all breaking changes are addressed - Release notes for the new version: --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license
# Conflicts: # packages/@aws-cdk/cdk-explorer/package.json # packages/aws-cdk/.projen/tasks.json # packages/aws-cdk/THIRD_PARTY_LICENSES # yarn.lock
Adds two read-only views to the `cdk explore` web UI. - **Construct tree** (`GET /api/tree`): the synthesized construct hierarchy. Each node is flagged with the highest severity of any policy violation on it, so problem areas are visible at a glance. - **Policy-validation panel** (`GET /api/policy-validation`): violations grouped by rule, sorted by severity, labeled with the originating plugin. The server reads the cloud assembly in `cdk.out` and returns a wire-stable, app-relative view. The backend owns the full transform from core construct node to displayed node, including default-child collapse and the per-node highest-severity join, so the frontend renders without re-deriving any of it. ## Out of scope - Navigation between a construct, its synthesized template, and its source. The wire model already carries `templateFile` and `sourceLocation`, but no navigation UI yet. - Frontend tests (adds deps, so future PR) frontend: <img width="1505" height="857" alt="Screenshot 2026-07-01 at 11 32 09 AM" src="https://github.com/user-attachments/assets/0086cdf4-175b-49a4-917e-ebb6bdf44f9d" /> ### Checklist - [ ] This change contains a major version upgrade for a dependency and I confirm all breaking changes are addressed - Release notes for the new version: --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license --------- Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Setting JSII_HOST_STACK_TRACES=1 on the synth subprocess makes jsii forward the host-language frames, so resolveFrames finds the .py/.java source. ### Checklist - [ ] This change contains a major version upgrade for a dependency and I confirm all breaking changes are addressed - Release notes for the new version: --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license
…1669) - Adds LSP hover on construct creation lines showing the resolved CloudFormation logical ID, resource type, construct path, and top-level CFN properties with values - Each property value links to its exact line in the synthesized template; the logical ID header links to the resource block - Multi-resource constructs show auxiliaries inline (≤5 listed individually, >5 collapsed to a type histogram like "6× Subnet, 3× RouteTable") - Extends `template-ranges.ts` with `resolveResourceRanges` / `indexTemplateRanges` to resolve per-property character ranges in a single parse - Exports `cfnProperties` from the construct tree builder so the hover has access to resolved property values example hover: <img width="1128" height="645" alt="Screenshot 2026-06-24 at 12 12 52 PM" src="https://github.com/user-attachments/assets/36451ea5-a753-43d0-a16a-293cf23ab776" /> <img width="1123" height="641" alt="Screenshot 2026-06-24 at 12 13 44 PM" src="https://github.com/user-attachments/assets/8320d612-fd1d-4c84-94aa-6eed9d7caa37" /> Fixes # ### Checklist - [ ] This change contains a major version upgrade for a dependency and I confirm all breaking changes are addressed - Release notes for the new version: --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license --------- Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…r stdio (#1670) Editors and AI agents start a language server by running a command over stdio, but the CDK Language Server (in `@aws-cdk/cdk-explorer`) has no such entry point. This adds one, so any LSP-capable editor or agent can get CDK diagnostics and CodeLens by pointing at `cdk lsp`. Wires up `cdk lsp` as a CLI subcommand that starts the server on stdin/stdout and runs until the client closes the channel. - Adds `@aws-cdk/cdk-explorer` as a runtime dependency so the server ships in the CLI bundle, version-aligned with the user's CDK toolchain. - Writes nothing to stdout (CLI logs already go to stderr), keeping the JSON-RPC channel clean. `applicationDir` comes from the LSP `initialize` options, so the command takes no arguments. - Mirrors the `cdk explore` wiring from #1598 Fixes # ### Checklist - [ ] This change contains a major version upgrade for a dependency and I confirm all breaking changes are addressed - Release notes for the new version: --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license
…#1711) startServer now requires toolkitBindingsFactory (added in #1634/#1669), but the cdk lsp command still called it with only { readable, writable }, breaking the build. Expose startLspServer() from cdk-explorer (wires the Toolkit bindings and starts the server) and call it from the CLI. main.ts becomes that exported function, making cdk lsp the single LSP entrypoint. Fixes # ### Checklist - [ ] This change contains a major version upgrade for a dependency and I confirm all breaking changes are addressed - Release notes for the new version: --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license
Adds live refresh to the cdk explore web UI. When the cloud assembly on disk changes, the server pushes an event and the SPA re-fetches, so the construct tree and violations stay current without a manual reload. - SSE stream (GET /api/events): a long-lived server-sent events channel. SseBroadcaster tracks connected clients and pushes to all of them, evicting any that disconnect. - cdk.out watcher: same watcher as LSP - SPA: subscribes on load and re-fetches the tree and violations on each event. - The event carries no payload. The server holds no assembly state, so the client just re-reads /api/tree and /api/policy-validation on receipt. Also narrows the web routes' injectable readAssembly seam to Promise<AssemblyReadResult> to match the real reader. ### Checklist - [ ] This change contains a major version upgrade for a dependency and I confirm all breaking changes are addressed - Release notes for the new version: --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license
Matching LSP side of #1706. Moves the assembly read-lock acquirer out of lib/lsp into lib/core/assembly-lock.ts so the LSP and web server build the read lock from one shared factory. Pure refactor, LSP behavior is unchanged, and server.ts re-exports AssemblyLock so existing importers keep resolving it. Fixes # ### Checklist - [ ] This change contains a major version upgrade for a dependency and I confirm all breaking changes are addressed - Release notes for the new version: --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license
megha-narayanan
temporarily deployed
to
run-tests
July 22, 2026 14:54 — with
GitHub Actions
Inactive
megha-narayanan
temporarily deployed
to
run-tests
July 22, 2026 14:54 — with
GitHub Actions
Inactive
megha-narayanan
temporarily deployed
to
run-tests
July 22, 2026 14:54 — with
GitHub Actions
Inactive
megha-narayanan
temporarily deployed
to
run-tests
July 22, 2026 14:54 — with
GitHub Actions
Inactive
megha-narayanan
temporarily deployed
to
run-tests
July 22, 2026 14:54 — with
GitHub Actions
Inactive
megha-narayanan
temporarily deployed
to
run-tests
July 22, 2026 14:54 — with
GitHub Actions
Inactive
megha-narayanan
temporarily deployed
to
run-tests
July 22, 2026 14:54 — with
GitHub Actions
Inactive
megha-narayanan
temporarily deployed
to
run-tests
July 22, 2026 14:54 — with
GitHub Actions
Inactive
megha-narayanan
temporarily deployed
to
run-tests
July 22, 2026 14:54 — with
GitHub Actions
Inactive
megha-narayanan
temporarily deployed
to
run-tests
July 22, 2026 14:54 — with
GitHub Actions
Inactive
megha-narayanan
temporarily deployed
to
run-tests
July 22, 2026 14:54 — with
GitHub Actions
Inactive
megha-narayanan
temporarily deployed
to
run-tests
July 22, 2026 14:54 — with
GitHub Actions
Inactive
megha-narayanan
temporarily deployed
to
run-tests
July 22, 2026 14:54 — with
GitHub Actions
Inactive
megha-narayanan
temporarily deployed
to
run-tests
July 22, 2026 14:54 — with
GitHub Actions
Inactive
megha-narayanan
temporarily deployed
to
run-tests
July 22, 2026 14:54 — with
GitHub Actions
Inactive
megha-narayanan
temporarily deployed
to
run-tests
July 22, 2026 14:54 — with
GitHub Actions
Inactive
megha-narayanan
temporarily deployed
to
run-tests
July 22, 2026 14:54 — with
GitHub Actions
Inactive
megha-narayanan
temporarily deployed
to
run-tests
July 22, 2026 14:54 — with
GitHub Actions
Inactive
megha-narayanan
temporarily deployed
to
run-tests
July 22, 2026 14:54 — with
GitHub Actions
Inactive
megha-narayanan
temporarily deployed
to
run-tests
July 22, 2026 14:54 — with
GitHub Actions
Inactive
megha-narayanan
temporarily deployed
to
run-tests
July 22, 2026 14:54 — with
GitHub Actions
Inactive
megha-narayanan
temporarily deployed
to
run-tests
July 22, 2026 14:54 — with
GitHub Actions
Inactive
megha-narayanan
temporarily deployed
to
run-tests
July 22, 2026 14:54 — with
GitHub Actions
Inactive
megha-narayanan
temporarily deployed
to
run-tests
July 22, 2026 14:54 — with
GitHub Actions
Inactive
megha-narayanan
temporarily deployed
to
run-tests
July 22, 2026 14:54 — with
GitHub Actions
Inactive
Contributor
|
Total lines changed 3530 is greater than 1000. Please consider breaking this PR down. |
mrgrain
reviewed
Jul 27, 2026
Contributor
There was a problem hiding this comment.
Works better if this file lives in frontend/tsconfig.json
mrgrain
requested changes
Jul 27, 2026
mrgrain
left a comment
Contributor
There was a problem hiding this comment.
Any chance we can replace with a smaller, more modern alternative? I suspect we only need a small subset of the features express offers.
https://e18e.dev/docs/replacements/express.html#replacements-for-express
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.
Merges the feat/cdk-explorer branch into main. The change is additive and introduces no behavior change to existing CLI commands.
Builds on the language server merged in #1681 and adds the web explorer: a new cdk explore command that serves a local, read-only web UI over a synthesized cloud assembly.
cdk explorecommand inpackages/aws-cdk. It starts a localhost web server over the cloud assembly in cdk.out, takes a single--portoption (default 4200), and does not synthesize.@aws-cdk/cdk-explorer(lib/web, lib/core, and the frontend SPA): an Express backend serving a small JSON API plus an embedded single-page app, and chokidar watchers for the assembly and the source tree.@aws-cdk/cloud-assembly-apitemplate-range resolution for the template viewer, and reads the synth-lock path exported from@aws-cdk/toolkit-libto detect when source files are stale relative to the last synth.Capabilities (folds in #1653, #1698, #1706, #1732, #1738):
Checklist
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license