Console acceptance checks
Target: WebStorm 2026.2.3, Bun 1.4+. Always-on debugging uses the approved Experimental DAP facade as documented in debugger-blocker.md.
Automated runtime checks
bun test .\tests\runtime\bootstrap.test.mjs
Checks persistent variables, TypeScript imports, bare export calls, global and
lexical collisions (including an undefined binding), preserving overwritten
bindings, switching modules, top-level await, sync/async/syntax errors, a failed
import retaining the previous context, output/control separation, and fresh state
after restart. They also cover uncaught errors not stopping the runtime, pending
awaits not blocking later commands, lazy (on first use) module execution, one
shared realm with project modules, and exposing non-exported declarations. All
fixtures are inside this development project or a temporary directory.
Platform and JVM checks
.\gradlew.bat -PwebstormPath="C:\path\to\WebStorm" test buildPlugin verifyPlugin
JVM tests cover the actual socket/process bridge, startup failure, stopping an infinite expression, and an IDE project fixture with file follow, pin, first-command queueing, restart, and retained history. Consult generated reports for actual results; merely having the test source is not a pass.
The panel regression test also creates its real input editor and invokes the
registered EditorUp/EditorDown handlers. It covers recalled multiline commands,
draft restoration, history boundaries, ordinary caret movement, completion-popup
priority, and unaffected file editors. It checks the configured editor font,
input lexer coloring after text replacement, and colored command transcript replay.
This is a headless platform test, not a physical-keyboard/focus acceptance test.
History regression coverage includes editing multiple recalled commands and revisiting them in both directions without losing changes. The highlighting test appends the user’s Date/toISOString/split/filter/reduce chain incrementally, checks semantic method colors across the entire chain at each stage, then checks deletion and clearing/recall. Interactive confirmation remains necessary because the fixture drives analysis explicitly rather than through a focused window.
The output-color test snapshots actual semantic markup from the input, clears the
input, and verifies that every method plus the global Boolean keeps its color in
the printed command. Result strings receive lexical colors. The completion test
accepts lexical and an export from an added file with Tab, evaluating both bare
identifiers in Bun, while checking that ordinary files receive no console-specific
suggestions. A separate test edits a loaded TS file and confirms that a project
export absent from the running context cannot insert an auto-import. It then
reimports the file without resetting console variables, checks that Tab inserts
the new export as a bare identifier and evaluates it, and repeats the refresh
for an added file. An edited imported dependency requests a full Restart.
Service tests queue opening and Restart from ModalityState.any() with modified
physical documents, then verify evaluation uses the saved contents. Clear is
tested through its menu action, including preserved draft/history/runtime and empty
transcript on reattachment.
Import tests parse raw default/named/aliased/namespace/side-effect declarations,
including semicolon-free input and escaped module strings. Strings, comments and
dynamic imports stay unchanged. Service tests execute the user’s import path
example, reuse path in another command and import aliases from a sibling TS file.
Runtime tests cover repeat imports, live exports after switching context,
collisions, missing modules/exports, and recovery after errors.
Additional-file tests import two TS modules beside a following main context,
check automatic collision/default aliases, live bindings, and removal. The IDE
fixture checks added-file restoration after Restart and that removing the file
does not remove an independently added symbol.
Plugin Verifier reports this build Compatible for WebStorm 2026.2.3. The 20 explicitly approved Experimental DAP usages are informational; internal, deprecated, override-only and other failure categories remain fatal.
Automated debugger checks
BunDebuggerTest checks a regular TypeScript breakpoint, reading frame locals,
Step Over, Continue and completion of the original console call.
BunDebuggerServiceTest checks that the same console input routes to the paused
frame and that Restart creates a working new runtime/session.
BunDebuggerModuleInitializationTest checks string-local evaluation, the exact
TypeScript pause line, and automatic console-runtime restart after editing a file
with an enabled breakpoint. All run in an isolated headless WebStorm profile and
require a local Node.js interpreter for the bundled Bun debug adapter.
Source inspections still pending
The separate IntelliJ source-inspection gate has NOT run. The only installed IDE
found is WebStorm; the JVM inspections needed for the Kotlin plugin are supplied
by IntelliJ IDEA / Qodana for JVM. A profile with verified inspection IDs is
prepared at config/inspections/api-usage.xml. It needs a JVM-capable inspection
environment and an imported project with the correct SDK/dependencies. Plugin
Verifier passing is not recorded as a substitute for this source inspection gate.
Reference inspection IDs: UnstableApiUsage, UnstableTypeUsedInSignature, NonExtendableApiUsage, OverrideOnly.
Remaining interactive checks in an isolated IDE
Launch runIde only with separate config/system/plugin directories (the Gradle
configuration uses build/isolated-ide). Open a disposable JS/TS project.
- Before opening Bun Console, no Bun backend should exist.
- Click its stripe button: UI appears immediately, and typing during startup works.
- Check highlighting/completion, multiline Enter, Ctrl+Enter, Up/Down history.
Fill the input with more lines than it can show and verify that
the mouse wheel scrolls the input while the pointer is over it. Drag its
upper divider to change the input height.
In Settings → Tools → Bun Console, switch to Enter-to-run. Verify Enter runs,
Shift+Enter inserts an indented newline, Ctrl+Enter no longer runs, and Enter
still accepts an open completion suggestion. Switch back and verify the
default keys return without reopening the console.
Edit a recalled command, visit another entry with Up/Down, then return: the
edited value must remain. Gradually extend
new Date().toISOString()with.split(/\D/).filter(Boolean).reduce((a, b) => a + b)and verify that earlier method names keep their semantic colors after each edit settles. Runconst value = 1; value, recall it, change it toconst value = 2; value, and run again: the second result and a subsequentvaluequery should both be2. Twoconst valuedeclarations in one command must still fail. - Open a TS file exporting
twice(x: number), then calltwice(21)->42. - Pin file
a.ts, switch tob.ts, and verify both are available as[a.ts · pinned] [b.ts · follows editor]withb.tsselected. Return toa.ts: its pinned tab should be selected, and there should be no duplicate follows-editor tab. Unpin it and verify it disappears from the pinned context after switching again. - Restart: prior text stays, variables disappear, current/pinned exports return.
- Run
while (true) {}and use Restart; the IDE must remain responsive. - Close the project; its own Bun process and socket should be released.
- Complete
lexwith Tab in the context of the fixture’sa.ts: input must belexical, without an inserted import; execute it successfully. Then addexport const initialText = 'new'to the loaded file. Completion must not insertimportwhile the runtime still has the old module. Focus the console input: it should reimport the file without losing console variables. Completeiniwith Tab and evaluateinitialText. - Clear: output disappears, the input/history/variables remain; new output works.
- Verify the stripe icon is white on the selected blue background in dark/light themes, and commands in the output retain the semantic colors of the input.
- Run
import path from 'path'followed bypath.join(process.cwd(), 'texts')in the same command, then reusepathin a later command. Repeat the import; it should succeed. Import a sibling file’s export with an alias, switch context files, and confirm the alias still works. - Open Settings → Tools → Bun Console. Switch between automatic detection and an explicit Bun path; invalid paths must not be saved. Apply while a console variable exists: it must remain available until Restart. Reopen settings and restart the test IDE to confirm the choice is retained. The toolbar must have no Bun picker button. Confirm Start console with debugger is off by default: opening/restarting Bun Console must create no Debug session, and ordinary evaluation must work. Enable it, Apply, and verify the current runtime is not interrupted; after Restart Runtime, breakpoint support should be active.
- Verify the tool window’s native ⋮ menu contains the console commands and its standard IDE window-management options. Pin File Context must show a check mark matching the active state. Run Input is disabled for blank input; Ctrl+Enter executes from the input, including with completion open, and does not replace shortcuts in ordinary editors. Confirm the selected file/runtime status is visible in the header. The compact Run button beside the input should execute on click and display the currently configured shortcut.
-
From a second TS file’s editor or Project-tree menu choose Add File to JS Console. Its exports should work alongside the current file, and the header should show one native tab per context file (
[a.ts · pinned] [b.ts · follows editor]), without a combined+ 1 filelabel. Clicking a pinned tab should open its file in the editor and select that tab while preserving the same console input, transcript, and runtime. Switch editor tabs and Restart: those exports and completion suggestions should remain. Then choose Remove File from JS Console; its added names should disappear while the current file and other added files remain. A non-exported top-level variable must stay inaccessible. Give both files an export calledshared:sharedmust refer to the file following the editor, and each value must be reachable viaglobalThis['a.ts'].sharedorglobalThis['b.ts'].shared. Repeat with twoa.tsfiles in different folders and verify both pills and namespace keys expand to uniquefolder/a.tspaths. Runconst shared = 42twice with different values: the short name must show the latest console value, whileglobalThis['a.ts'].sharedstill shows the file export. - Open Bun Console and verify startup leaves Bun Console selected rather than
switching to Debug. Even if Debug appears briefly during adapter startup, it
must be hidden and Bun Console must then be shown and activated. With a
breakpoint inside
twice, runtwice(21): Debug should activate only when execution pauses. The status line above the input should showpaused at ...;xandytyped into the same input should evaluate to21and42. Step Over and Continue in the native menu should work, and Continue should finish the original command under its original number. While paused, switch back to Bun Console and evaluate another local or expression in the selected frame. Restart while paused should close only this console’s process and create a fresh debug-capable runtime. After the console has already loaded a file, add a new breakpoint in that file and immediately call its function: execution should pause there without a manual restart. Bun Inspector startup text should use a neutral console color, while actual errors remain red. Edit a file that has an enabled breakpoint and run its function again: the plugin should automatically restart only the console runtime and pause on the correct source line, never on the module’s first line. Finally, stop the Debug session and run another console expression: Bun Console and its current Bun runtime should continue without breakpoints. Restart Runtime should reconnect Debug. - Click the Debugger toggle in the console title bar: the runtime restarts once with the debugger (transcript, history and file tabs remain); clicking again restarts without it.
- Open a file whose top level logs something: switching to it must not print that log; the first console call of one of its functions does. Call a non-exported top-level function of the file by name.
- Run
await new Promise(r => setTimeout(r, 5000)), then1 + 1at once:2appears immediately, the header showsrunning…, and the first result arrives later under its own number. - Run
Promise.reject(new Error('x'))andsetTimeout(() => { throw 1 }): both printUncaught …in red and earlier variables still exist. - Run
while (true) {}: after about two seconds the header says JavaScript is busy and shows Restart Runtime. RunBun.spawn(['bun', '-e', 'setInterval(() => {}, 1000)'])and Restart: the spawned process must exit. - Run
console.log(1); console.error(2); 3:1,2(red) and then[N] 3appear in this order, every time. - Start a small Node.js or Bun script with WebStorm’s own Debug and stop it at a
breakpoint. In Bun Console (Debugger toggle off), the status line shows
paused in <session> at file:line; a local variable typed into the console evaluates in that frame. Continue from the ⋮ menu resumes the script; the next input runs in the console’s Bun runtime again. - Settings → Plugins shows the Bun Console icon, description and vendor.
Do not install into, attach to, restart, or change settings of the user’s working WebStorm without explicit approval.