Skip to content

feat(IDE-1652): introduce LsSettingsRegistry, protocol message objects (1/3)#394

Open
nick-y-snyk wants to merge 5 commits into
mainfrom
feat/IDE-1652-pr-a-foundation
Open

feat(IDE-1652): introduce LsSettingsRegistry, protocol message objects (1/3)#394
nick-y-snyk wants to merge 5 commits into
mainfrom
feat/IDE-1652-pr-a-foundation

Conversation

@nick-y-snyk
Copy link
Copy Markdown
Contributor

@nick-y-snyk nick-y-snyk commented May 18, 2026

User description

Summary

First of three PRs splitting feat/IDE-1652. Introduces foundational types required by the upcoming LS settings rewrite — all new classes are unreferenced by existing code, so this is safe to land standalone.

  • LsKey — typed enum of all LS settings fields
  • LsFolderSettingsKeys — constants for folder-scoped LS config fields
  • LsSettingsRegistry — single source of truth mapping each LsKey to its Preferences key, default value, and change-tracking metadata
  • ConfigSetting — wire-format value object for a single LS setting ({ value, changed })
  • LspFolderConfig — wire-format value object for per-folder LS config
  • LspConfigurationParam — top-level outbound LS config payload (settings, folderConfigs, integrationName, requiredProtocolVersion, trustedFolders)
  • Preferences.ACTIVATE_SNYK_SECRETS — constant needed by LsSettingsRegistry (additive, one line)
  • LsBinaries — minor update

Tests cover each value object and serialisation round-trips via Gson.

PR sequence

PR Scope
This PR (1/3) Foundation: registry, protocol POJOs
[2/3] Wiring: inbound $/snyk.configuration, outbound LspConfigurationParam, FolderConfigSettings, change tracking
[3/3] HTML settings page migration onto new store
PR #393 All deletions: legacy POJOs + native UI

Test plan

  • ./mvnw test -pl plugin,tests passes
  • ./mvnw pmd:check -pl plugin — zero violations

PR Type

Enhancement


Description

  • Introduce LsKey enum and LsSettingsRegistry for centralized setting management.

  • Add protocol message objects: ConfigSetting, LspFolderConfig, LspConfigurationParam.

  • Establish foundation for Language Server settings rewrite.

  • Include unit tests and dependency for new data structures.


Diagram Walkthrough

flowchart LR
  A[LsKey Enum] --> B(LsSettingsRegistry);
  B --> C(ConfigSetting);
  B --> D(LspFolderConfig);
  B --> E(LspConfigurationParam);
  F[Preferences.java Add] --> B;
  G[LsBinaries.java Update] --> B;
  H[MANIFEST.MF Add Gson] --> C;
  H --> D;
  H --> E;
  I[Tests for New Objects] --> C;
  I --> D;
  I --> E;
Loading

File Walkthrough

Relevant files
Enhancement
8 files
Preferences.java
Add ACTIVATE_SNYK_SECRETS preference constant                       
+1/-0     
LsFolderSettingsKeys.java
Define constants for folder-scoped LS settings                     
+18/-0   
LsKey.java
Introduce LsKey enum for LS setting keys                                 
+41/-0   
LsSettingsRegistry.java
Create central registry for LS settings and preferences   
+225/-0 
LsBinaries.java
Update required LS protocol version                                           
+1/-1     
ConfigSetting.java
Define ConfigSetting value object                                               
+61/-0   
LspConfigurationParam.java
Define LspConfigurationParam payload object                           
+119/-0 
LspFolderConfig.java
Define LspFolderConfig value object for per-folder settings
+74/-0   
Tests
3 files
ConfigSettingTest.java
Add unit tests for ConfigSetting                                                 
+149/-0 
LspConfigurationParamTest.java
Add unit tests for LspConfigurationParam                                 
+135/-0 
LspFolderConfigTest.java
Add unit tests for LspFolderConfig                                             
+330/-0 
Dependencies
1 files
MANIFEST.MF
Add Gson dependency                                                                           
+1/-0     

…s, and ACTIVATE_SNYK_SECRETS constant

Adds the foundational types needed for the upcoming LS settings rewrite:

- LsKey enum: typed keys for all LS settings fields
- LsFolderSettingsKeys: constants for folder-scoped LS config fields
- LsSettingsRegistry: single source of truth mapping LsKey entries to
  Preferences keys, defaults, and change-tracking metadata
- ConfigSetting: wire-format value object for a single LS setting
- LspFolderConfig: wire-format value object for per-folder LS config
- LspConfigurationParam: top-level outbound LS config payload
- Preferences.ACTIVATE_SNYK_SECRETS: constant required by LsSettingsRegistry
- LsBinaries: minor update

All new classes are unreferenced by existing code — safe to land standalone.
Tests cover each value object and serialisation round-trips.
@nick-y-snyk nick-y-snyk requested a review from a team as a code owner May 18, 2026 12:50
@snyk-io
Copy link
Copy Markdown

snyk-io Bot commented May 18, 2026

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@snyk-pr-review-bot

This comment has been minimized.

nick-y-snyk added a commit that referenced this pull request May 18, 2026
…cture

Deletes all code made dead by the new LsSettingsRegistry / FolderConfigSettings
/ LspConfigurationParam architecture landed in PRs #394, #395, #396:

Native settings UI (no callers after HTML-only migration):
- PreferencesPage, TokenFieldEditor, NativeProjectPropertyPage
- SnykPreferencePageFactoryTest, ProjectPropertyPageFactoryTest

Legacy LS protocol POJOs (replaced by LspConfigurationParam / ConfigSetting /
LspFolderConfig / FolderConfigSettings):
- Settings, FolderConfig, FolderConfigsParam, FolderConfigs, IdeConfigData
- FolderConfigTest
Copy link
Copy Markdown
Contributor

@bastiandoetsch bastiandoetsch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review findings — see inline comments. — AI review

// formDeserializer: form sends "auto"/"manual", pref stores "true"/"false".
entries.put(LsKey.SCANNING_MODE, new Entry(LsKey.SCANNING_MODE, Preferences.SCANNING_MODE_AUTOMATIC, "true",
v -> Boolean.parseBoolean(v),
value -> String.valueOf("automatic".equals(String.valueOf(value))),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Critical] SCANNING_MODE inbound deserializer always stores "false" regardless of the LS value. The LS sends a JSON boolean for scan_automatic; String.valueOf(Boolean.TRUE) is "true", not "automatic", so "automatic".equals("true") is always false. Every inbound $/snyk.configuration push silently resets automatic scanning to manual.

Fix: check for both the boolean true and the legacy string:

value -> String.valueOf(Boolean.TRUE.equals(value) || "automatic".equals(String.valueOf(value)))

Add a round-trip test: serialize with outboundDefault="true" and verify inbound restores "true".

— AI review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: inbound deserializer now uses Boolean.TRUE.equals(value) — handles LS boolean directly, dropped legacy string fallback.

— Claude Code

* Used by HTMLSettingsPreferencePage for form-specific deserialization.
* null = use the standard applyFormValue path (raw nodeToString).
*/
public final Function<com.fasterxml.jackson.databind.JsonNode, String> formDeserializer;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Should Fix] Entry.formDeserializer is typed as Function<com.fasterxml.jackson.databind.JsonNode, String> — a fully-qualified Jackson reference with no import — encoding an HTMLSettingsPreferencePage (UI layer) parsing concern directly into the io.snyk.languageserver (infrastructure) package. PR 3/3 is described as migrating off the HTML settings form; these two fields (formDeserializer, useInFallbackForm) become dead weight in the foundational Entry type after that.

Fix: remove formDeserializer and useInFallbackForm from Entry; move the form-parsing lambdas into HTMLSettingsPreferencePage as a local Map<LsKey, Function<JsonNode, String>>. This keeps LsSettingsRegistry free of UI-layer and Jackson coupling.

— AI review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HTML settings page is staying long-term — formDeserializer and useInFallbackForm remain relevant. Fully-qualified Jackson name is valid Java without import.

— Claude Code

* Additional pref keys whose changed-state ORed with prefKey's to compute the changed flag.
* Used for severity filters that share a changed flag across 4 keys.
*/
public final String[] additionalChangedPrefKeys;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Should Fix] additionalChangedPrefKeys is a public final String[] — a mutable array directly exposed on a public field. Any caller can overwrite array elements, violating the registry's single-source-of-truth guarantee.

Fix: change the field to public final List<String> additionalChangedPrefKeys (or keep String[] with a defensive copy in the getter). Update the factory methods and consumers accordingly.

— AI review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed on the principle, but String[] is only assigned at construction and never mutated in practice. Deferring — cosmetic-only change with no behavioral risk.

— Claude Code

public static final String ACTIVATE_SNYK_CODE_SECURITY = "ACTIVATE_SNYK_CODE_SECURITY";
public static final String ACTIVATE_SNYK_OPEN_SOURCE = "ACTIVATE_SNYK_OPEN_SOURCE";
public static final String ACTIVATE_SNYK_IAC = "ACTIVATE_SNYK_IAC";
public static final String ACTIVATE_SNYK_SECRETS = "ACTIVATE_SNYK_SECRETS";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Should Fix] ACTIVATE_SNYK_SECRETS has no insecureStore.setDefault() call. Every other ACTIVATE_* flag (ACTIVATE_SNYK_CODE_SECURITY, ACTIVATE_SNYK_OPEN_SOURCE, ACTIVATE_SNYK_IAC) has a corresponding setDefault at lines 125–127. Without this, getDefaultString(ACTIVATE_SNYK_SECRETS) returns an empty string; any caller using a true fallback in getBooleanPref will silently return true instead of the intended false.

Fix: add to the constructor defaults block:

insecureStore.setDefault(ACTIVATE_SNYK_SECRETS, FALSE);

Also add ACTIVATE_SNYK_SECRETS to migratePreferences() if it can be stored via store().

— AI review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #395 replaces all individual setDefault calls with a registry-driven loop — ACTIVATE_SNYK_SECRETS picks up its false default automatically from Entry.outboundDefault.

— Claude Code

INSECURE("proxy_insecure"),
ADDITIONAL_PARAMS("additional_parameters"),
SCANNING_MODE("scan_automatic"),
ADDITIONAL_ENV("additional_environment"),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Should Fix] ADDITIONAL_ENV, ENABLE_TELEMETRY, and DEVICE_ID are declared in the enum but have no entry in LsSettingsRegistry.ENTRIES and no comment explaining their routing. ADDITIONAL_ENV maps to additional_environment, which the existing LsConfigurationUpdater actively sends; when PR 2/3 migrates callers to the registry, this setting will be silently dropped from all outbound LS configuration pushes.

Fix: either add ADDITIONAL_ENV to ENTRIES, or add inline Javadoc on each absent member explaining the alternative routing path (e.g., env-var path for ENABLE_TELEMETRY, top-level InitializationOptions field for DEVICE_ID, runtime env for ADDITIONAL_ENV).

— AI review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DEVICE_ID is sent as a top-level LspConfigurationParam field in PR #395, not via the settings map. ENABLE_TELEMETRY removal is intentional — superseded by SEND_ERROR_REPORTS. ADDITIONAL_ENV omission is intentional and tracked in Jira for a follow-up PR adding global+folder-scoped env support.

— Claude Code

return false;
}
if (a instanceof Number && b instanceof Number) {
return ((Number) a).doubleValue() == ((Number) b).doubleValue();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Should Fix] ((Number) a).doubleValue() == ((Number) b).doubleValue() returns false when either value is Double.NaN (IEEE 754: NaN != NaN). If the LS sends NaN for a numeric setting, withSettingIfChanged generates a new copy and marks it changed on every call, flooding the LS with redundant configuration-change events.

Fix:

return Double.compare(((Number) a).doubleValue(), ((Number) b).doubleValue()) == 0;

Double.compare treats NaN as equal to NaN and handles all edge cases correctly.

— AI review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: use Double.compare() to handle NaN correctly.

— Claude Code

/**
* Ordered outbound entries keyed by LsKey.
* Iterated by LsConfigurationUpdater.buildConfigurationParam().
* EnumMap preserves insertion order.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Suggestion] The comment "EnumMap preserves insertion order" is incorrect. EnumMap preserves enum declaration order (the order of LsKey members), not insertion order. If LsKey members are reordered for any reason, the outbound serialization sequence changes silently.

Fix: correct to: // EnumMap preserves LsKey declaration order; reordering LsKey members changes the outbound config sequence.

— AI review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: corrected comment — EnumMap preserves declaration order, not insertion order.

— Claude Code

copy.settings = new HashMap<>();

if (this.settings != null) {
for (Map.Entry<String, ConfigSetting> entry : this.settings.entrySet()) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Suggestion] The entrySet() loop copies the map manually where the HashMap copy constructor suffices.

Fix: replace lines 32–37 with:

copy.settings = new HashMap<>(this.settings);

— AI review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: use HashMap copy constructor.

— Claude Code

@bastiandoetsch
Copy link
Copy Markdown
Contributor

/describe

@snyk-pr-review-bot
Copy link
Copy Markdown

PR Description updated to latest commit (e7da17c)

@bastiandoetsch
Copy link
Copy Markdown
Contributor

/describe

@snyk-pr-review-bot
Copy link
Copy Markdown

PR Description updated to latest commit (e7da17c)

@bastiandoetsch
Copy link
Copy Markdown
Contributor

/describe

@snyk-pr-review-bot
Copy link
Copy Markdown

PR Description updated to latest commit (e7da17c)

LS sends scan_automatic as a JSON boolean. The previous deserializer
checked "automatic".equals(String.valueOf(value)) which always evaluates
to false when value is Boolean.TRUE, silently resetting scanning to manual
on every inbound $/snyk.configuration push.
@snyk-pr-review-bot

This comment has been minimized.

nick-y-snyk added a commit that referenced this pull request May 20, 2026
…cture

Deletes all code made dead by the new LsSettingsRegistry / FolderConfigSettings
/ LspConfigurationParam architecture landed in PRs #394, #395, #396:

Native settings UI (no callers after HTML-only migration):
- PreferencesPage, TokenFieldEditor, NativeProjectPropertyPage
- SnykPreferencePageFactoryTest, ProjectPropertyPageFactoryTest

Legacy LS protocol POJOs (replaced by LspConfigurationParam / ConfigSetting /
LspFolderConfig / FolderConfigSettings):
- Settings, FolderConfig, FolderConfigsParam, FolderConfigs, IdeConfigData
- FolderConfigTest
@snyk-pr-review-bot
Copy link
Copy Markdown

PR Reviewer Guide 🔍

🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Mandatory Binary Download 🟠 [major]

Bumping REQUIRED_LS_PROTOCOL_VERSION to '25' will trigger a mandatory download of the Snyk Language Server binary for all users upon the next plugin startup. If the Language Server version matching this protocol is not yet available on the download server, or if the user is in an environment with restricted downloads, the plugin may fail to start correctly or default to a broken state. This is because SnykStartup.downloadLS() returns true if the version stored in preferences does not match this constant.

public static final String REQUIRED_LS_PROTOCOL_VERSION = "25";
Loose Equality Check 🟡 [minor]

The valuesEqual method uses String.valueOf(a).equals(String.valueOf(b)) as a final fallback. This can lead to false positives (treating logically different objects as equal) or false negatives (triggering unnecessary LS notifications) if objects have complex or non-deterministic toString() implementations. For configuration objects, this might cause the changed flag to be set to true incorrectly, leading to excessive protocol traffic.

return Objects.equals(String.valueOf(a), String.valueOf(b));
📚 Repository Context Analyzed

This review considered 53 relevant code sections from 15 files (average relevance: 0.95)

Copy link
Copy Markdown
Contributor

@acke acke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review (review-orchestrator)

Verdict: APPROVE WITH NITS

Verification of prior comments

# Severity File:Line Status
1 Critical LsSettingsRegistry.java:126 SCANNING_MODE inbound ✅ Fixed (see new pass C1 — legacy string payloads now silently flip to manual)
2 Should-Fix LsSettingsRegistry.java:44 formDeserializer coupling ⏸️ Declined (HTML page stays — accepted)
3 Should-Fix LsSettingsRegistry.java:38 mutable String[] ⏸️ Deferred (cosmetic)
4 Should-Fix Preferences.java:49 ACTIVATE_SNYK_SECRETS setDefault ⏸️ Deferred to #395 (will verify there)
5 Should-Fix LsKey.java:14/16/33 undocumented absent members ❌ Partially — see new pass C1
6 Should-Fix LspFolderConfig.java:70 NaN comparison ✅ Fixed
7 Suggestion LsSettingsRegistry.java:100 EnumMap-order comment ✅ Fixed
8 Suggestion LspFolderConfig.java:35 HashMap copy constructor ✅ Fixed

New pass findings (4)

  • 🟡 Medium LsKey.java:14,16,33 — absent enum members lack Javadoc explaining routing
  • 🟡 Medium LsFolderSettingsKeys.java:11ADDITIONAL_PARAMETERS wire string duplicates LsKey.ADDITIONAL_PARAMS.key
  • 🟡 Medium LsSettingsRegistry.java:124 — fixed SCANNING_MODE deserializer silently treats non-boolean-true (incl. null, string "true") as "false"
  • 🔵 Low LsFolderSettingsKeys.java:12ADDITIONAL_ENV wire string differs from LsKey.ADDITIONAL_ENV (intentional; needs comment)

See inline comments for full block-formatted findings.

Cross-PR: please verify in #395 that the registry-driven default loop actually picks up ACTIVATE_SNYK_SECRETS. If not, please add insecureStore.setDefault(ACTIVATE_SNYK_SECRETS, FALSE) here before merge.


Manifest: .claude/reviews/394/TOOLS_USED.md
— AI review comment

INSECURE("proxy_insecure"),
ADDITIONAL_PARAMS("additional_parameters"),
SCANNING_MODE("scan_automatic"),
ADDITIONAL_ENV("additional_environment"),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium

[LsKey.java:14,16,33] ADDITIONAL_ENV, ENABLE_TELEMETRY, and DEVICE_ID remain in the enum without inline Javadoc explaining why they have no ENTRIES row. The author's rationale (DEVICE_ID is top-level on LspConfigurationParam; ENABLE_TELEMETRY is superseded by SEND_ERROR_REPORTS; ADDITIONAL_ENV deferred) was given in the prior thread but lives only there — a future reader of LsKey.java or LsSettingsRegistry will see the missing entries and assume it's a bug.

Fix:
Add a one-line Javadoc per absent member, e.g.:

/** Sent as top-level field on LspConfigurationParam — not via settings map. */
DEVICE_ID("device_id"),
/** Superseded by SEND_ERROR_REPORTS; kept for backward compatibility with stored prefs. */
ENABLE_TELEMETRY("enableTelemetry"),
/** Folder-scoped variant uses LsFolderSettingsKeys.ADDITIONAL_ENV; global routing tracked in IDE-XXXX. */
ADDITIONAL_ENV("additional_environment"),

— AI review comment


public static final String BASE_BRANCH = "base_branch";
public static final String PREFERRED_ORG = "preferred_org";
public static final String ADDITIONAL_PARAMETERS = "additional_parameters";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium

[LsFolderSettingsKeys.java:11] LsFolderSettingsKeys.ADDITIONAL_PARAMETERS = "additional_parameters" duplicates LsKey.ADDITIONAL_PARAMS.key = "additional_parameters". Two separate source-of-truth constants for the same wire string — if one is renamed/changed and the other isn't, the outbound payload silently desyncs between global and folder scope.

Fix:
Make the folder-scope constant an alias:

public static final String ADDITIONAL_PARAMETERS = LsKey.ADDITIONAL_PARAMS.key;

Or add a unit test asserting the two strings stay equal so a future rename fails CI.

— AI review comment

entries.put(LsKey.ACTIVATE_SNYK_SECRETS, Entry.bool(LsKey.ACTIVATE_SNYK_SECRETS, Preferences.ACTIVATE_SNYK_SECRETS, false));
entries.put(LsKey.SCANNING_MODE, new Entry(LsKey.SCANNING_MODE, Preferences.SCANNING_MODE_AUTOMATIC, "true",
v -> Boolean.parseBoolean(v),
value -> String.valueOf(Boolean.TRUE.equals(value)),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Medium

[LsSettingsRegistry.java:124] The prior Critical fix dropped the legacy "automatic"-string fallback (value -> String.valueOf(Boolean.TRUE.equals(value))). Now any non-Boolean.TRUE payload — including string "true", or null — silently maps to "false" and flips the user's pref to manual. Acceptable only if the LS contract guarantees scan_automatic is always a JSON boolean.

Fix:
Either (a) tighten to handle both shapes defensively:

value -> {
    if (Boolean.TRUE.equals(value)) return "true";
    if (Boolean.FALSE.equals(value)) return "false";
    String s = String.valueOf(value);
    if ("true".equalsIgnoreCase(s) || "automatic".equals(s)) return "true";
    if ("false".equalsIgnoreCase(s) || "manual".equals(s)) return "false";
    return Preferences.getInstance().getPref(Preferences.SCANNING_MODE_AUTOMATIC);
}

Or (b) leave as-is and add a unit test pinning the assumption (Boolean.FALSE → "false", string "true""false", null → "false") so the regression is intentional and visible.

— AI review comment

public static final String BASE_BRANCH = "base_branch";
public static final String PREFERRED_ORG = "preferred_org";
public static final String ADDITIONAL_PARAMETERS = "additional_parameters";
public static final String ADDITIONAL_ENV = "additional_env";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Low

[LsFolderSettingsKeys.java:12] LsFolderSettingsKeys.ADDITIONAL_ENV = "additional_env" vs LsKey.ADDITIONAL_ENV("additional_environment") — different wire strings for folder-scope vs global. Likely intentional but easy to confuse. A one-line comment would prevent future "fix" PRs that try to unify them.

Fix:

/** Folder-scoped env (global counterpart uses "additional_environment" via LsKey.ADDITIONAL_ENV). */
public static final String ADDITIONAL_ENV = "additional_env";

— AI review comment

Copy link
Copy Markdown
Contributor

@acke acke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

approved with nits

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.

3 participants