Skip to content

Extension/intellij#473

Draft
philmillman wants to merge 4 commits intomainfrom
extension/intellij
Draft

Extension/intellij#473
philmillman wants to merge 4 commits intomainfrom
extension/intellij

Conversation

@philmillman
Copy link
Member

A very messy first pass at a Jetbrains/IntelliJ/etc plugin

requires java17, gradle, and intellij (or webstorm) for testing

@changeset-bot
Copy link

changeset-bot bot commented Mar 23, 2026

⚠️ No Changeset found

Latest commit: dc6aadd

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Comment on lines +43 to +57
runs-on: ubuntu-latest
defaults:
run:
working-directory: packages/intellij-plugin
steps:
- uses: actions/checkout@v6
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: "17"
distribution: "temurin"
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build IntelliJ plugin
run: ./gradlew build

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium test

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 2 days ago

To fix the problem, explicitly restrict the GITHUB_TOKEN permissions in the workflow. The simplest approach is to add a workflow-level permissions: block that applies to all jobs. Since the jobs only need to check out code and do local builds/tests, contents: read is sufficient in most cases and matches the recommended minimal starting point.

The best fix without changing existing behavior is:

  • Add a permissions: section near the top of .github/workflows/test.yaml, at the workflow root (same level as name: and on:), specifying contents: read.
  • This will apply to both build and intellij-plugin jobs, because they do not define their own permissions blocks.
  • No additional imports or methods are needed; this is a pure YAML configuration adjustment.

Concretely:

  • In .github/workflows/test.yaml, insert:
permissions:
  contents: read

between the existing on: block and jobs: block (e.g., after line 5, before line 7). This resolves the CodeQL warning by explicitly limiting the GITHUB_TOKEN.

Suggested changeset 1
.github/workflows/test.yaml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
--- a/.github/workflows/test.yaml
+++ b/.github/workflows/test.yaml
@@ -3,6 +3,8 @@
   pull_request:
   push:
 
+permissions:
+  contents: read
 
 jobs:
   build:
EOF
@@ -3,6 +3,8 @@
pull_request:
push:

permissions:
contents: read

jobs:
build:
Copilot is powered by AI and may make mistakes. Always verify output.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds an initial JetBrains/IntelliJ plugin for the @env-spec language (syntax highlighting, completion, inspections) and updates the existing VS Code extension logic/tests to better distinguish “real” decorator comment lines from regular comments (plus improved header/item scope handling). It also wires IntelliJ plugin builds into CI.

Changes:

  • Add a new packages/intellij-plugin Gradle/Kotlin plugin with lexer/highlighting, completion contributor, inspection diagnostics, and tests.
  • Refine VS Code extension completion/diagnostics parsing: ignore decorator-like text in non-decorator comments and improve header vs item scope detection.
  • Add CI job to build the IntelliJ plugin and update ESLint ignore list for the plugin build output.

Reviewed changes

Copilot reviewed 41 out of 51 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
packages/vscode-plugin/test/diagnostics-provider.test.ts Adds regression test for header decorator block behavior across blank lines.
packages/vscode-plugin/test/diagnostics-core.test.ts Adds tests for ignoring decorator-like text in regular/post-comments and repeatable function decorators.
packages/vscode-plugin/test/completion-core.test.ts Expands tests for header vs item scope + decorator comment parsing rules.
packages/vscode-plugin/src/diagnostics-provider.ts Updates env assignment parsing (export/dots/hyphens) + header-block handling; exports validateDocument for testing.
packages/vscode-plugin/src/diagnostics-core.ts Tightens decorator occurrence parsing to only consider real decorator comment lines and tracks function-call occurrences.
packages/vscode-plugin/src/completion-provider.ts Uses stricter decorator-comment prefix detection before offering decorator completions.
packages/vscode-plugin/src/completion-core.ts Adds decorator-comment prefix detection and improves header vs item scope logic.
packages/intellij-plugin/src/test/kotlin/dev/dmno/envspec/EnvSpecLexerTest.kt Adds lexer tests for decorator/value tokenization and mid-line lexing.
packages/intellij-plugin/src/test/kotlin/dev/dmno/envspec/EnvSpecDiagnosticsCoreTest.kt Adds diagnostics core tests (duplicates, incompatibles, enum validation, type parsing).
packages/intellij-plugin/src/test/kotlin/dev/dmno/envspec/EnvSpecCompletionCoreTest.kt Adds completion core tests (header detection, decorator collection, enum extraction, type option context).
packages/intellij-plugin/src/test/kotlin/dev/dmno/envspec/EnvSpecCompletionContributorTest.kt Adds completion contributor tests for edge match cases and snippet normalization.
packages/intellij-plugin/src/main/resources/icons/env-spec.svg Adds plugin icon resource.
packages/intellij-plugin/src/main/resources/META-INF/plugin.xml Registers language, file type, completion, inspections, docs provider, commenter, enter handler, etc.
packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecTokenTypes.kt Defines token types for lexer/highlighter.
packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecSyntaxHighlighterFactory.kt Registers syntax highlighter factory.
packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecSyntaxHighlighter.kt Maps token types to IntelliJ color keys.
packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecParserDefinition.kt Basic parser definition wiring for IntelliJ PSI.
packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecParser.kt Minimal parser that advances lexer to EOF.
packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecLexer.kt Implements a line-oriented lexer with decorator/value segmentation.
packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecLanguage.kt Declares the EnvSpec language.
packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecInspection.kt Adds an inspection that runs decorator + static value validation.
packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecFileType.kt Registers .env / .env.* file type + icon.
packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecFile.kt PSI file implementation for EnvSpec.
packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecDocumentationProvider.kt Hover docs for decorators using the catalog.
packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecDiagnosticsCore.kt Kotlin port of diagnostics core (type parsing + validation + decorator diagnostics).
packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCompletionCore.kt Kotlin completion helpers (header detection, decorator filtering, enum extraction).
packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCompletionContributor.kt IntelliJ completion contributor for decorators/types/options/resolvers/references with snippet normalization.
packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCommenter.kt Enables toggle line comment (# ).
packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCommentEnterHandler.kt Adds “continue # comment” behavior on Enter.
packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecColorSettingsPage.kt Adds a color scheme page for Env Spec tokens.
packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecCatalog.kt Adds decorator/type/resolver catalog used for completion/docs.
packages/intellij-plugin/src/main/kotlin/dev/dmno/envspec/EnvSpecASTWrapperPsiElement.kt PSI wrapper element implementation.
packages/intellij-plugin/settings.gradle.kts Sets Gradle root project name.
packages/intellij-plugin/gradlew Adds Gradle wrapper script.
packages/intellij-plugin/gradle/wrapper/gradle-wrapper.properties Configures Gradle wrapper distribution.
packages/intellij-plugin/gradle/wrapper/gradle-wrapper.jar Adds Gradle wrapper jar.
packages/intellij-plugin/gradle.properties Gradle JVM args + IntelliJ platform warning suppression.
packages/intellij-plugin/build.gradle.kts Configures Kotlin/IntelliJ plugin build, runIde, tests, toolchain.
packages/intellij-plugin/README.md Adds plugin README (features, install, dev, troubleshooting).
packages/intellij-plugin/CONTEXT.md Adds compressed context doc about plugin architecture and workflows.
packages/intellij-plugin/.gitignore Adds package-level ignores for Gradle/IDE caches and build output.
eslint.config.mjs Ignores IntelliJ plugin build output in ESLint.
.idea/vcs.xml Adds IntelliJ project config (should not be committed).
.idea/varlock.iml Adds IntelliJ module file (should not be committed).
.idea/modules.xml Adds IntelliJ modules config (should not be committed).
.idea/inspectionProfiles/Project_Default.xml Adds IntelliJ inspection profile config (should not be committed).
.idea/codeStyles/codeStyleConfig.xml Adds IntelliJ code style config (should not be committed).
.idea/codeStyles/Project.xml Adds IntelliJ code style settings (should not be committed).
.idea/.gitignore Adds nested gitignore under .idea/.
.github/workflows/test.yaml Adds CI job to build the IntelliJ plugin with JDK 17.
Files not reviewed (7)
  • .idea/.gitignore: Language not supported
  • .idea/codeStyles/Project.xml: Language not supported
  • .idea/codeStyles/codeStyleConfig.xml: Language not supported
  • .idea/inspectionProfiles/Project_Default.xml: Language not supported
  • .idea/modules.xml: Language not supported
  • .idea/varlock.iml: Language not supported
  • .idea/vcs.xml: Language not supported


object EnvSpecDiagnosticsCore {

private val DECORATOR_PATTERN = Regex("@([A-Za-z][\\w-]*)(?:\\([^)]*\\)|=[^\\s#]+)?")
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

DECORATOR_PATTERN will match @decorator text anywhere in a comment line (including plain docs like # this @required mention... or # @todo:), which can produce false diagnostics. Recommend restricting parsing to actual decorator comment lines (eg ^\s*#\s*@) and stripping post-comments.

Suggested change
private val DECORATOR_PATTERN = Regex("@([A-Za-z][\\w-]*)(?:\\([^)]*\\)|=[^\\s#]+)?")
private val DECORATOR_PATTERN = Regex("^\\s*#\\s*@([A-Za-z][\\w-]*)(?:\\([^#]*\\)|=[^\\s#]+)?")

Copilot uses AI. Check for mistakes.
Comment on lines +228 to +232
if (i < text.length && text[i] == '(') {
queue.add(QueuedToken(start + i, start + i + 1, EnvSpecTokenTypes.EQUALS))
val close = findClosingParen(text, i)
if (close > i + 1) {
enqueueDecoratorArgsTokens(start + i + 1, text.substring(i + 1, close))
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

The lexer emits EnvSpecTokenTypes.EQUALS for ( when parsing decorator calls. This makes the token stream ambiguous and ties non-equals punctuation to a misleading token type name. Consider introducing dedicated token types (or a generic punctuation token) for parens instead of reusing EQUALS.

Copilot uses AI. Check for mistakes.
Comment on lines +71 to +73
companion object {
private val ENV_ASSIGNMENT = Pattern.compile("^\\s*([A-Za-z_][A-Za-z0-9_]*)\\s*=\\s*(.*?)\\s*$")
}
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

The assignment matcher here doesn’t recognize export KEY=... or keys containing . / -, even though the lexer and VS Code side now accept those. This will prevent diagnostics from running on valid env-spec assignments (and can break reference collection/completion parity). Update ENV_ASSIGNMENT to match the lexer’s assignment regex (optional export + [A-Za-z0-9_.-] in keys).

Copilot uses AI. Check for mistakes.
@philmillman
Copy link
Member Author

@copilot implement all of your review feedback

Copy link
Contributor

Copilot AI commented Mar 23, 2026

@philmillman I've opened a new pull request, #474, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI and others added 2 commits March 23, 2026 17:11
* Initial plan

* Implement all review feedback: paren tokens, decorator filtering, key patterns, .idea gitignore

Co-authored-by: philmillman <3722211+philmillman@users.noreply.github.com>
Agent-Logs-Url: https://github.com/dmno-dev/varlock/sessions/45f827c0-165e-457c-83dc-538993ffa1bd

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: philmillman <3722211+philmillman@users.noreply.github.com>
Comment on lines +21 to +46
name: Validate IntelliJ plugin
runs-on: ubuntu-latest
defaults:
run:
working-directory: packages/intellij-plugin
steps:
- uses: actions/checkout@v6
with:
ref: ${{ github.event.inputs.ref }}
- name: Load plugin env vars (varlock)
uses: dmno-dev/varlock-action@v1.0.1
with:
working-directory: packages/intellij-plugin
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: "17"
distribution: "temurin"
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Run IntelliJ plugin tests
run: ./gradlew test
- name: Verify plugin compatibility (JetBrains Plugin Verifier)
run: ./gradlew verifyPlugin

build-artifacts:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI about 23 hours ago

In general, to fix this problem you should explicitly declare a permissions block in the workflow (either at the top level or per job) and set the least privileges required. For a build/test/publish pipeline that only checks out code, runs builds, uploads artifacts, and talks to external services, the GITHUB_TOKEN usually only needs contents: read; no write access to the repository is required.

For this specific workflow in .github/workflows/extensions-release.yaml, the simplest and safest fix that does not change functionality is:

  • Add a top‑level permissions block right after the on: section (before concurrency: or jobs:).
  • Set contents: read as the only permission, which is sufficient for actions/checkout@v6 and does not grant write privileges to the repository.
  • Leave the jobs themselves unchanged; they will inherit this minimal permission.

If later you discover a step that needs additional scopes (e.g., pull-requests: write), that can be added either at the workflow level or for that specific job, but with the current snippet there is no indication such permission is needed.

Concretely, edit .github/workflows/extensions-release.yaml to insert:

permissions:
  contents: read

between the on: block (ending at line 15–16) and concurrency: (line 17).

Suggested changeset 1
.github/workflows/extensions-release.yaml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/extensions-release.yaml b/.github/workflows/extensions-release.yaml
--- a/.github/workflows/extensions-release.yaml
+++ b/.github/workflows/extensions-release.yaml
@@ -14,6 +14,9 @@
         default: false
         type: boolean
 
+permissions:
+  contents: read
+
 concurrency: ${{ github.workflow }}-${{ github.ref }}
 
 jobs:
EOF
@@ -14,6 +14,9 @@
default: false
type: boolean

permissions:
contents: read

concurrency: ${{ github.workflow }}-${{ github.ref }}

jobs:
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines +47 to +73
name: Build IntelliJ plugin artifact
runs-on: ubuntu-latest
needs: [validate-intellij]
steps:
- uses: actions/checkout@v6
with:
ref: ${{ github.event.inputs.ref }}
- name: Load plugin env vars (varlock)
uses: dmno-dev/varlock-action@v1.0.1
with:
working-directory: packages/intellij-plugin
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: "17"
distribution: "temurin"
- name: Build IntelliJ plugin zip
working-directory: packages/intellij-plugin
run: chmod +x gradlew && ./gradlew buildPlugin
- name: Upload IntelliJ artifact
uses: actions/upload-artifact@v4
with:
name: intellij-plugin-zip
path: packages/intellij-plugin/build/distributions/*.zip
if-no-files-found: error

publish-intellij:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI about 23 hours ago

In general, this should be fixed by explicitly setting a permissions block that grants only the minimal scopes required. Since the jobs only need to check out code and upload artifacts, they only require contents: read for actions/checkout. No other scopes (e.g., issues, pull-requests, contents: write) are needed.

The best fix without changing behavior is to add a top-level permissions block to .github/workflows/extensions-release.yaml (so it applies to all jobs) with contents: read. This constrains the GITHUB_TOKEN across validate-intellij, build-artifacts, and publish-intellij. No job-specific overrides are required because none of the jobs do repository writes or GitHub API modifications. Concretely, insert:

permissions:
  contents: read

after the on: block (e.g., after line 16), or at any valid top-level position before jobs:. No imports or additional methods are required.

Suggested changeset 1
.github/workflows/extensions-release.yaml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/extensions-release.yaml b/.github/workflows/extensions-release.yaml
--- a/.github/workflows/extensions-release.yaml
+++ b/.github/workflows/extensions-release.yaml
@@ -14,6 +14,9 @@
         default: false
         type: boolean
 
+permissions:
+  contents: read
+
 concurrency: ${{ github.workflow }}-${{ github.ref }}
 
 jobs:
EOF
@@ -14,6 +14,9 @@
default: false
type: boolean

permissions:
contents: read

concurrency: ${{ github.workflow }}-${{ github.ref }}

jobs:
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines +74 to +97
name: Publish IntelliJ plugin
runs-on: ubuntu-latest
if: github.event.inputs.publish == 'true'
needs: [build-artifacts]
defaults:
run:
working-directory: packages/intellij-plugin
steps:
- uses: actions/checkout@v6
with:
ref: ${{ github.event.inputs.ref }}
- name: Load plugin env vars (varlock)
uses: dmno-dev/varlock-action@v1.0.1
with:
working-directory: packages/intellij-plugin
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: "17"
distribution: "temurin"
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Publish IntelliJ plugin
run: ./gradlew publishPlugin

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI about 23 hours ago

In general, the fix is to explicitly specify minimal GITHUB_TOKEN permissions for the workflow or individual jobs. Since none of the jobs write to the repository or to GitHub resources, they only need read access to repository contents so that actions/checkout can function. The safest and simplest fix is to add a top-level permissions block with contents: read, which will apply to all jobs that do not override it, including publish-intellij.

Concretely, edit .github/workflows/extensions-release.yaml and insert a top-level permissions section after the on: block (or anywhere at the root level). For example:

permissions:
  contents: read

This restricts the GITHUB_TOKEN to only reading repository contents while preserving all existing behavior: checkout still works, builds/tests run as before, artifacts upload as before, and the Gradle-based publishing to JetBrains Marketplace is unaffected because it presumably uses its own credentials (e.g., secrets or env vars) rather than the GITHUB_TOKEN.

No extra imports or methods are required, just the YAML configuration change.

Suggested changeset 1
.github/workflows/extensions-release.yaml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/extensions-release.yaml b/.github/workflows/extensions-release.yaml
--- a/.github/workflows/extensions-release.yaml
+++ b/.github/workflows/extensions-release.yaml
@@ -14,6 +14,9 @@
         default: false
         type: boolean
 
+permissions:
+  contents: read
+
 concurrency: ${{ github.workflow }}-${{ github.ref }}
 
 jobs:
EOF
@@ -14,6 +14,9 @@
default: false
type: boolean

permissions:
contents: read

concurrency: ${{ github.workflow }}-${{ github.ref }}

jobs:
Copilot is powered by AI and may make mistakes. Always verify output.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants