Skip to content

fix(jetbrains): support IntelliJ 2026.3 terminal API - #8

Merged
edelauna merged 2 commits into
mainfrom
fix-ide-terminal
Oct 2, 2026
Merged

edelauna merged 2 commits into
mainfrom
fix-ide-terminal

Conversation

@edelauna

@edelauna edelauna commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Replace the ProxyPtyProcess stream wrapper with RawOutputTtyConnector, a ProcessTtyConnector subclass. It forwards every decoded output chunk to the extension host exactly once.
  • One plugin binary supports IntelliJ builds 233 (2023.3) and 263 (2026.3).
  • Add connector tests, a packaged bytecode scan, an exact-build Plugin Verifier step, and a headless dispatch smoke check as pull-request and release gates.

Root cause

IntelliJ 2026.3 (build 263.5701.42) changed the terminal startup API. LocalTerminalDirectRunner.createProcess(ShellStartupOptions) no longer returns PtyProcess. It returns java.lang.Process, and the session enters through createTtyConnector(ShellStartupOptions). The old createProcess override and the ProxyPtyProcess wrapper do not resolve on 2026.3. The terminal fails to start there.

Solution

  • TerminalInstance starts the PTY itself with PtyProcessBuilder. Both platform paths share startTerminalProcess.
  • The runner keeps the 2023.3 overrides, createProcess and createTtyConnector(PtyProcess). It declares createTtyConnector(ShellStartupOptions) without override. The descriptor matches the 2026.3 platform method, so virtual dispatch binds at runtime.
  • No method calls a platform super that does not exist on both builds.
  • RawOutputTtyConnector extends jediterm ProcessTtyConnector. The (java.lang.Process, Charset) constructor descriptor is the same in build 233 and build 263. One compiled super call resolves on both. The platform PtyProcessTtyConnector is not usable as the superclass. Its constructor takes PtyProcess on 233 and java.lang.Process on 2026.3.
  • close() mirrors the JetBrains local terminal connector. Unix processes get SIGHUP first. The path destroys them one second later if they survive. Windows ConPTY processes get the ETX interrupt byte on stdin before destroy. The path destroys other processes at once. super.close does not run, because it destroys at once and removes the one second grace window.
  • resize() skips a dead process, matching the platform connector on both builds. The charset is UTF-8, the same value the platform connector uses.

Support boundary

The bridge is local-only. It starts a PtyProcess on the local machine. WSL-internal terminals, dev-container terminals, and RemDev sessions are out of scope. On 2026.3 those sessions carry non-local EEL descriptors. This bridge implements no EEL support. The RemDev frontend stops at the inherited platform guard and never reaches this runner.

Validation

  • RawOutputTtyConnectorTest covers output forwarding, multibyte decode at every byte boundary, write encoding and flush, SIGHUP close on a real Unix PTY, Windows-style destroy, resize behavior, and inherited lifecycle methods.
  • verifyPackagedBytecode scans the packaged plugin jar. It rejects every reference to the createProcess descriptor that 2026.3 removed. The check task runs it.
  • runPluginVerifier (verifier 1.410) checks the plugin against exact IC-263.5701.42. CI downloads the EAP archive, checks the SHA-256 pinned in gradle.properties, and passes the unpacked IDE with -PverifierLocalIde. The task fails only on compatibility problems and invalid plugin results. Deprecation notices do not hide real failures.
  • smoke263Dispatch runs headless against the exact 2026.3 build. It proves the createTtyConnector(ShellStartupOptions) dispatch binds. It proves no packaged class references the removed createProcess. It proves the connector decodes and forwards output against this IDE build jediterm and pty4j binaries.
  • .github/workflows/pr.yml runs the connector tests, the build, the bytecode scan, the verifier, and the smoke check on every pull request. release.yml runs the same gates with the same -P flags as the publish step. The verified artifact is the shipped zip.

Release notes

  • The JetBrains plugin starts terminals on IntelliJ 2026.3. One binary serves builds 233 through 263.
  • Terminal close follows the platform behavior. Unix gets SIGHUP with a one second grace. Windows ConPTY gets the ETX interrupt byte.
  • Local terminals only. WSL-internal, dev-container, and RemDev terminals are not supported.
  • Versions 3.82.2 and 3.84.0 need separate validation through these gates before you redeploy them. Do not redeploy them from the old build.

Replace process-stream interception with a ProcessTtyConnector that
supports the legacy and modern terminal startup paths.

Preserve terminal output forwarding, command execution, Unix shutdown,
and Windows ConPTY interrupt handling. Add connector tests, packaged
bytecode checks, exact 2026.3 verifier coverage, and pull-request gates.

Document that the compatibility bridge supports local terminals only.
@edelauna
edelauna merged commit e2bcab1 into main Oct 2, 2026
1 check passed
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.

1 participant