feat(secrets): add Snyk Secrets product type [IDE-1126][IDE-1749]#788
feat(secrets): add Snyk Secrets product type [IDE-1126][IDE-1749]#788bastiandoetsch merged 57 commits intomasterfrom
Conversation
Implement Phase 7 of the HTML tree view integration. When the
IntelliJ Registry flag `snyk.useHtmlTreeView` is enabled, the native
Swing tree + severity toolbar in SnykToolWindowPanel is replaced with
a JCEF-based HtmlTreePanel that renders server-driven HTML from the
`$/snyk.treeView` LSP notification.
Changes:
- Add `snyk.useHtmlTreeView` registry key in plugin.xml
- Add `isHtmlTreeViewEnabled()` helper in Utils.kt
- Add `SnykTreeViewParams` data class and `SnykTreeViewListener` topic
- Add `@JsonNotification("$/snyk.treeView")` handler in SnykLanguageClient
- Add `executeCommandWithArgs()` public method on LanguageServerWrapper
- Add `TreeViewBridgeHandler` with unified `__ideExecuteCommand__` JS bridge
- Add `HtmlTreePanel` JCEF panel subscribing to tree view notifications
- Conditionally swap TreePanel/HtmlTreePanel in SnykToolWindowPanel
- Hide native ViewActions and expand/collapse toolbar when flag is ON
- Add unit tests for bridge dispatch logic and LSP notification handler
…wBridgeHandler [IDE-1750] - Add HtmlTreePanelTest: init, dispose, JCEF null path, notification handling, resource file validation, placeholder replacement - Add executeCommandWithArgs tests to LanguageServerWrapperTest: not-initialized guard, successful execution, argument passing, null result - Extend TreeViewBridgeHandlerTest: concurrent dispatch, LS exception handling, null callbackExecutor, default values, missing fields
…DE-1750] - Remove result != null guard in dispatchCommand so callbacks fire even when LanguageServerWrapper.executeCommandWithArgs returns null (e.g. navigateToRange side-effect commands). Prevents leaked entries in window.__ideCallbacks__ and stalled UI state. - Change snyk.useHtmlTreeView registry key to restartRequired=true since the panel swap only happens at SnykToolWindowPanel init time. - Update test to assert callback IS invoked with null result (TDD).
- Fix JCEF browser memory leak: store browser as field, dispose in dispose() - Replace SimpleToolWindowPanel with JPanel (fixes UiDataProvider warning) - Add command allowlist to TreeViewBridgeHandler (security hardening) - Add callbackId validation regex to prevent JS injection - Skip native tree refresh when HTML tree view is enabled (performance) - Replace Thread.sleep with Awaitility in tests - Add tests for buildBridgeScript, ALLOWED_COMMANDS, and all new guards
Add JBCefApp.isSupported() check before creating HtmlTreePanel to prevent blank panel on systems without JCEF support. Falls back to native Swing TreePanel gracefully.
…ion [IDE-1750] The LS snyk.navigateToRange command calls window/showDocument with a file URI back to the client. The previous implementation fell through to super.showDocument() which threw UnsupportedOperationException. Now handles file URIs by resolving the VirtualFile and navigating to the selection range. Unsupported schemes return ShowDocumentResult(false) gracefully instead of throwing.
…etNodeExpanded [IDE-1750] The JS tree view uses snyk.setNodeExpanded for expand/collapse state persistence but it was missing from the allowlist. snyk.getTreeView was listed but never used by the JS.
…[IDE-1750] - onShowIssueDetail: bypass native tree search when HTML tree enabled, directly create SuggestionDescriptionPanel from cached ScanIssue - HtmlTreePanel: skip loadHTML when raw HTML hash unchanged to prevent tree collapse on redundant LS re-emissions
- showDocument: match any snyk:// URI with showInDetailPanel action, not just Snyk Code. Map product string to correct ProductType. - onShowIssueDetail: bypass native tree for HTML tree mode, directly create SuggestionDescriptionPanel from cached ScanIssue. - Add diagnostic logging to trace showDocument and cache lookup flow.
…or [IDE-1750] Add 7 missing --vscode-* CSS variable mappings needed by the HTML tree view styles.css: tree-indentGuidesStroke, sideBar-background, badge-background/foreground, list-activeSelectionBackground/Foreground, list-hoverBackground.
- Add HtmlTreePanel.selectNode() to execute __selectTreeNode__ JS bridge - Store HtmlTreePanel reference in SnykToolWindowPanel - Wire selectNodeAndDisplayDescription to also select in HTML tree - Expands ancestor nodes and scrolls issue into view
Wire onShowIssueDetail to also call htmlTreePanel.selectNode when processing snyk:// showDocument requests, so the tree highlights the corresponding issue node.
- Add HtmlTreePanel.reset() to reload initial empty HTML - Call reset() from doCleanUi so 'Clean all results' clears the HTML tree
…750] TreeViewInit.html now renders the same structure as the LS tree: - Filter toolbar with severity SVG buttons (all active) - Expand/collapse all buttons - 3 product nodes (Open Source, Code Security, Infrastructure As Code) with their inline SVG icons, matching the LS tree.html template - Uses the same CSS classes for theme integration via var(--vscode-*)
When isHtmlTreeViewEnabled(), selectNodeAndDisplayDescription now directly loads SuggestionDescriptionPanel instead of relying on native JTree node lookup (which may not have nodes populated). Fixes gutter icon click sometimes not updating the description panel.
… offset [IDE-1750] - Extract duplicated HTML tree description panel update logic into private selectNodeInHtmlTreeAndShowDescription method, called from both onShowIssueDetail and selectNodeAndDisplayDescription. - Fix unsafe offset calculation in showDocument file URI handler by clamping startOffset/endOffset to document.textLength, preventing IndexOutOfBoundsException when character exceeds line length.
…E-1750] Add tests for: - reset() reloads init HTML into browser - reset() skipped after dispose - reset() no-op when JCEF is null - selectNode() no-op when JCEF is null - duplicate HTML content is skipped (hash check) HtmlTreePanel coverage: 71.2% -> 86.4%
…st [IDE-1750] Add snyk.showScanErrorDetails and snyk.updateFolderConfig to the JCEF bridge allowlist so tree.js can invoke them via __ideExecuteCommand__.
Add snyk.showScanErrorDetails and snyk.updateFolderConfig to the expected commands in TreeViewBridgeHandlerTest.
This comment has been minimized.
This comment has been minimized.
5f1c290 to
ef6bc18
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
… silent file loss [IDE-1749]
Replace non-atomic toList().also { clear() } with removeIf-based drain in
flushPendingAnnotationRefreshes. A file added between toList() and clear() was
silently dropped and would only be re-queued on the next diagnostic update.
With ConcurrentHashMap.newKeySet().removeIf, each element is removed and
collected atomically per-element. Any file added after the drain has passed its
bucket stays in the set and is processed on the next flush cycle — never lost.
Extract the drain into internal drainPendingAnnotationRefreshFiles() for
testability. Add table tests covering empty, single, multiple, and pre-drain
concurrent-add scenarios.
This comment has been minimized.
This comment has been minimized.
|
/describe |
This comment has been minimized.
This comment has been minimized.
|
PR Description updated to latest commit (ba502ea) |
…sSeverityEnablementChanged [IDE-1749] These calls had no effect after their return values were unassigned — the methods have no side effects, so calling them without using the result is pure dead code.
This comment has been minimized.
This comment has been minimized.
|
/describe |
|
PR Description updated to latest commit (0ab243f) |
There was a problem hiding this comment.
Annotation Refresh moved to Cache
| displaySnykCodeResults(results) | ||
| this.snykToolWindowPanel.triggerSelectionListeners = true | ||
| } | ||
| refreshAnnotationsForOpenFiles(project) |
There was a problem hiding this comment.
moved to cache
| ) | ||
| } | ||
|
|
||
| @Test |
There was a problem hiding this comment.
Tests the parser bug (IDE-1126)
| "snyk.toggleTreeFilter", | ||
| listOf("severity", "high", true), | ||
| ) | ||
| await().atMost(2, TimeUnit.SECONDS).untilAsserted { |
There was a problem hiding this comment.
Fix flaky under windows
Code reviewFound 1 issue:
snyk-intellij-plugin/src/main/kotlin/io/snyk/plugin/Utils.kt Lines 228 to 232 in 0ab243f 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
nick-y-snyk
left a comment
There was a problem hiding this comment.
Looks good to me, claude found "bug" in isScanRunning
| val SNYK_SCAN_TOPIC = Topic.create("Snyk scan LS", SnykScanListener::class.java) | ||
| } | ||
|
|
||
| // these update the tree and should not be needed for the HTML tree anymore |
There was a problem hiding this comment.
leaked from another pr?
There was a problem hiding this comment.
nevermind, I see it's merged
| return if (this.additionalData.riskScore > 0) { | ||
| severityPriority + this.additionalData.riskScore | ||
| } else { | ||
| severityPriority + this.additionalData.priorityScore |
There was a problem hiding this comment.
is it possible that both riskScore and priorityScore are present?
good catch, Claude :) |
PR Reviewer Guide 🔍
|
User description
Summary
Add Snyk Secrets as a new product type to the IntelliJ plugin, enabling editor annotations, caching, and Language Server integration for secrets scanning results.
Changes
New Files
SnykSecretsAnnotator.kt— Editor annotator for Snyk Secrets issues (mirrorsSnykCodeAnnotator)secrets.svg/secrets_disabled.svg— Product iconsSnykCachedResultsTest.kt— Tests for secrets cache, product map lookup, and LsProduct mappingModified Files
ProductType.kt— AddedSECRETSenum entry; renamed IAC treeName to "Snyk Infrastructure as Code"Types.kt— AddedSecretstoLsProductenum; addedSECRETSfilterable type; updatedtitle(),issueNaming(),details()for SECRETSSnykCachedResults.kt— AddedcurrentSecretsResultsLSandcurrentSecretsError; moved annotation refresh debouncing fromSnykToolWindowPanelSnykLanguageClient.kt— HandleLsProduct.Secretsin diagnostics pipeline and AI fix actionsUtils.kt— AddedisSnykSecretsRunning()andSECRETSbranch ingetSnykCachedResultsForProductCodeActionIntention.kt— Added SECRETS icon and title (wasTODO()crash)SnykApplicationSettingsStateService.kt— AddedsecretsScanEnabledsettingSnykScanListener.kt— AddedscanningSecretsFinished()SnykToolWindowPanel.kt— Removed annotation refresh logic (moved toSnykCachedResults); secrets use HTML tree viewSnykToolWindowSnykScanListener.kt— Handle secrets scan lifecycleTests
ScanIssueTestfor SECRETS-specific methodsSnykCachedResultsTestfor secrets cache and LsProduct mappingSnykToolWindowSnykScanListenerTestfor IAC treeName changeVerification
PR Type
Enhancement
Description
Add support for Snyk Secrets scanning.
Integrate secrets scanning results into the plugin.
Centralize annotation refresh logic for performance.
Update data models and UI for the new product.
Diagram Walkthrough
flowchart LR A[New Product Type: Secrets] --> B(Data Model Updates); B --> C(UI Integration); B --> D(Annotator Integration); E[Annotation Refresh Logic] --> F(Centralized in Cache); D --> G(Plugin.xml); C --> H(Tool Window Panel); B --> I(Settings Service); B --> J(Utils); J --> K(Secrets Running Check); I --> L(Secrets Enabled Flag); F --> M(SnykCachedResults); M --> N(DaemonCodeAnalyzer); subgraph Core Plugin A B C D E F G H I J K L M N endFile Walkthrough
12 files
Add Snyk Secrets iconsAdd secrets running check and cache lookupAdd secrets scan enablement settingUse ParametersListUtil for CLI arguments parsingClear secrets cache and handle scan completionAdd Snyk Secrets product typeAdd secrets cache, centralize annotation refresh logicSupport Snyk Secrets in code actionsImplement Snyk Secrets annotatorHandle Snyk Secrets in LSP communicationAdd LsProduct.Secrets and update ScanIssue for secretsRegister Snyk Secrets annotator1 files
Minor comment updates for scan listener2 files
Guard CLI download if not auto-managedEnsure baseBranch has default value2 files
Remove annotation refresh logic, note secrets use HTML viewRefactor file issue retrieval for cache lookup5 files
Test parsing of CLI arguments for folder configsUpdate tests to use await for async verificationsUpdate IAC tree name and verify root nodesAdd tests for secrets cache and annotation refresh drainAdd tests for ScanIssue handling of Snyk Secrets type