Sno Station
Sno Station은 AI 에이전트를 하나의 팀으로 묶는 오픈소스 워크스테이션으로, 로컬 머신에서 에이전트 협업을 가능하게 함
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기An interactive JavaScript and TypeScript console for WebStorm, running on Bun.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
An interactive JavaScript and TypeScript console for WebStorm, running on Bun .
Call the functions of the file you are editing, try snippets, and debug them — without leaving the IDE.
• Why
• Requirements
• Installation
• Quick start
• Running code
• Your files as the console context
• Imports
• Long-running code and errors
• Debugging
• Settings
• Troubleshooting
• Limitations
• How it works
• Building from source
• LicenseREADME 전문 보기 ↗You wrote parse() in parser.ts and want to see what it returns for a few inputs.
Usually that means a scratch file, a test, or copying code into a browser console.
With Bun Console you open parser.ts, open the console and type parse("abc").
const, let and class can be declared
again, so you can keep refining the same line.If you have used the developer console of a browser, most of it will feel familiar.
| Component | Requirement |
|---|---|
| IDE | WebStorm, IntelliJ IDEA Ultimate, PhpStorm, PyCharm or GoLand 2026.2 or newer (verified); other JetBrains IDEs with JavaScript support (RubyMine, Rider, …) should work too |
| Runtime | Bun 1.4 or newer — console code runs on it |
| Debugger (optional) | The Bun plugin (bundled with WebStorm; in IntelliJ IDEA install it from Settings → Plugins → Marketplace) and a Node.js interpreter configured in the IDE — the Bun debug adapter runs on Node.js |
From JetBrains Marketplace: Settings → Plugins → Marketplace, search for Bun Console, click Install — or use Install to IDE on the plugin page.
From a file: download bun-console-<version>.zip from the
releases, then Settings → Plugins → ⚙ → Install
Plugin from Disk… and select the zip. No IDE restart is needed.
Make sure Bun is installed:
bun --version
Open a JavaScript or TypeScript file of your project, for example:
// parser.ts
const separators = /[\s,;]+/;
export function tokenize(text: string): string[] {
return text.split(separators).filter(Boolean);
}
Open the console: View → Tool Windows → Bun Console, click its > button on the bottom
tool-window bar, or find it with Find Action (Ctrl+Shift+A) as "JavaScript Console" or "REPL".
Type an expression and press Ctrl+Enter:
tokenize("a, b;c") // [ 'a', 'b', 'c' ]
separators.source // '[\\s,;]+' — not exported, still available
The tab above the output shows which file is the context (parser.ts · follows editor).
Switch to another file in the editor and the console follows it.
The console does nothing until you use it: when the IDE reopens a project with the tool window open, Bun is not started until you click into the input, run a command or use a console action. While the tool window is hidden, the console does not follow the editor either; it catches up when you show it again.
| Action | Keys |
|---|---|
| Run the input | Ctrl+Enter (or the Run button) |
| New line | Enter |
| Previous / next command | Up / Down on the first / last line, or Alt+Up / Alt+Down |
| Completion | as in the editor (Ctrl+Space) |
You can swap Enter and Ctrl+Enter in Settings (Enter runs, Shift+Enter adds a line). The run shortcut can be changed in Settings → Keymap → Run Bun Console Input.
[3] > 1 + 1 → [3] 2.
Values are printed completely — every array item, every nesting level, whole strings —
on one line when they fit the console width, otherwise laid out for that width (long arrays of
numbers or strings fill the whole width). (Only output
longer than 5 million characters is cut, with a note, to keep the IDE responsive.)console.log, console.error, console.table and process.stdout.write
appears before the command's result, in order. Warnings are yellow and errors are red.const total = 42 stays available in later commands and appears in
completion. Declaring total again replaces it, as in a browser console. Declaring the
same name twice in one command is still an error.await works: await fetch("https://example.com").then(r => r.status).console.clear() empties the transcript but keeps variables, history
and input.The console input is JavaScript. TypeScript files are loaded and debugged normally, but type annotations typed into the console itself are not supported (code you run from a TypeScript file with Run Selection may have them, see below).
Two buttons in the console's title bar (also in the editor's context menu) run code straight from the editor:
| Button | What runs |
|---|---|
| Run File (▶) | the whole file in the editor, as a program: its top-level code runs again now, and its output (and errors) appear in the console |
| Run Selection (▶ with a text cursor) | the code selected in the editor, exactly as if you typed it into the console: it gets a number, goes into the history, and its declarations stay |
await included —
that is the point of the button. It also runs a file from the Project view's context menu.var a = 0 at the top of
scratch.js, selecting console.log(a + 12) prints 12, and a function of the file that
changes a changes that same a. A value counts as stated when it is built from literals,
functions, other such names, and built-ins that run no code of yours (new Map(),
Math.max(1, 2), JSON.parse("…"), 'a,b'.split(',')); connect() or fetch(…) do not
count. For such a name (or a name of another file that has not run) the selection stops with
ReferenceError: db is from scratch.js, which has not run yet, and a notification offers
Run scratch.js, then the selection. The file's imports do load, as they would for any
import, so its functions can use them. Code selected in a TypeScript (or JSX) file is
compiled to JavaScript first, so type annotations, as, generics and enums work. While a debugged
program is paused, the selection is evaluated in its stack frame (there types are not compiled).Editor on the left, console on the right (as in JS Bin): in the console's ⋮ menu choose Move to → Right Top. To give it the full height of the window, turn on Settings → Appearance & Behavior → Appearance → Widescreen tool window layout.
The JS/TS file selected in the editor is the context: its top-level functions, classes,
variables and enums are available by name, whether they are exported or not. Names that are
already taken in the console (your own variables, globals like process) are left alone; the
transcript lists such collisions.
A context file is not executed when you open it. The console reads the file to learn its names; the module's top-level code runs the first time a command uses one of those names — once, like a normal import. The same applies to the files it imports.
If the whole module namespace is needed, it is available as globalThis['parser.ts'].
By default the console follows the editor: open another file and its names replace the previous file's names. Three commands keep names around while you move through the project:
| Command | Where | What stays available |
|---|---|---|
| Pin File Context | ⋮ menu of the console (a checkbox) | every top-level name of the current file |
| Add File to Bun Console | context menu of the editor or the Project tree | every top-level name of any JS/TS file, even one that is not open |
| Add Symbol to Bun Console | context menu of the editor, caret on a name | one top-level declaration |
Tabs. Each context file has a tab above the output: pinned and added files first
(store.ts · pinned), then the file following the editor (parser.ts · follows editor). Clicking a
tab opens that file in the editor. All tabs show one and the same console — the same input,
transcript and variables; the tabs only tell you which files' names are in scope.
Unpin / remove. Uncheck Pin File Context while that file is open, or use Remove File from Bun Console in its context menu. Its names disappear; your own variables stay.
Add Symbol works with the caret on a declaration (function tokenize, const separators,
class Parser) or on any reference to one. It understands export lists such as
export { tokenize as split } and names a default export after its declaration. Top-level
declarations can be added whether they are exported or not; declarations nested inside functions
are only reachable while paused in a frame where they are in scope (Debugging).
Where the console could not provide a value, the command is disabled and says why: a type
(interface, type), a declare or .d.ts declaration, an imported name (add it from its own
file), or a nested name.
Restart Runtime keeps all of it. Pinned files, added files and added symbols come back in the fresh runtime; only variables created by your commands are reset.
Name clashes. Your own variables and built-in globals (process, console, …) are never
replaced; the transcript lists names that were skipped. When two context files declare the same
name, the file following the editor keeps the short name and the other one gets an alias
(shared_2); the transcript says which. A default export of an added file is named after the file
(parser_default for parser.ts). Every context file is also reachable as a whole module:
globalThis['parser.ts'], or with the folder when file names repeat (globalThis['left/shared.ts'],
as on the tabs).
For example, to try a store together with the code that uses it:
// store.ts is open — pin it (⋮ → Pin File Context), then open app.ts
add("apple") // from store.ts (pinned)
render() // from app.ts (follows the editor)
items // store.ts's non-exported array: [ 'apple' ]
globalThis['store.ts'] // the whole module
Edit a context file and return to the console: it is saved and reloaded before your next command. Your console variables survive. If you changed a file that a context file only imports, the status line asks for Restart Runtime (the ↻ button in the title bar), because the old version is still in use by the modules that imported it.
Non-exported declarations become available by adding an export { … } list after the module's
last line when Bun loads it; line numbers, stack traces and breakpoints are unaffected. This is
also prepared for the files a context file imports, so their names are available when you open
them later. If a file was loaded some other way before the console knew about it (for example
through a dynamic import()), reading one of its non-exported names says that it needs
Restart Runtime.
CommonJS files (module.exports = …, .cjs or .js) work the same way, by another route:
an export list would turn them into ES modules, so the console registers getters for their
top-level names instead. module.exports stays exactly as the file sets it, and a name such as
let calls = 0 reads its current value. TypeScript compiled to CommonJS (.cts) shares only
its module.exports.
Static import statements work in the console, in all forms:
import path from 'path'
import { join as combine } from 'node:path'
import * as fs from 'node:fs'
import './setup'
import { tokenize } from './parser' // relative to the context file
path.basename(combine('a', 'b.txt'))
Imported names stay available until Restart Runtime. Relative paths resolve from the context
file, or from the project folder when there is none; packages and built-in modules resolve as
Bun resolves them. Importing a name that is already taken asks for an alias. Import attributes
(with { type: 'json' }) are not supported yet; dynamic import() works as usual.
Completion in the console offers what the running console actually has: context file names,
your variables and imports. It does not offer other project exports, because accepting one would
add an import line to the input.
await sleep(5000) keeps running while you type
and run other commands; its result is printed under its own number when it arrives.running… 3 s.while (true) {}), the status
line says so within a couple of seconds and the ↻ Restart Runtime button appears — the only way
to stop such code, as in a browser tab.Uncaught … / Uncaught (in promise) …, and the runtime keeps all its state.Bun.spawn, child servers) are ended by Restart Runtime
and when the project closes.instanceof Array, your classes and globalThis properties work across both.Turn the debugger on with the bug button in the console's title bar (or ⋮ → Debugger). The runtime restarts with WebStorm's Bun debugger attached; the transcript, history and file contexts stay.
Set a breakpoint in a context file and call the function from the console. Execution stops at
the breakpoint and the Debug window shows the stack and variables. The status line reads
paused at parser.ts:14; input evaluates in this frame, and:
Turn the debugger off with the same button when you don't need it. If you edit a file that has breakpoints, the console restarts its runtime before the next command so the breakpoints stay attached to the new code.
This works with the console's debugger off. Start your own Node.js or Bun program with
WebStorm's regular Debug, stop it at a breakpoint and open Bun Console: the status line shows
paused in <session> at file:line, and console input is evaluated in that program's selected
frame. Continue from the ⋮ menu or the Debug window; afterwards input goes back to the console's
own runtime.
Settings → Tools → Bun Console:
PATH (on macOS
including your login shell's PATH), then $BUN_INSTALL/bin, ~/.bun/bin, and Homebrew or
/usr/local locations. Clear Find Bun automatically to choose a file. The setting applies to
all projects on this computer and takes effect at the next Restart Runtime."Bun was not found." Install Bun 1.4+ or choose its executable in the settings. On macOS,
an IDE started from the Dock sees your shell's PATH only if the shell profile exports it.
"Bun Console requires Bun 1.4 or newer." Run bun upgrade.
"The debugger needs the Bun plugin". WebStorm bundles it; in IntelliJ IDEA and other IDEs install Bun from Settings → Plugins → Marketplace. The console itself works without it.
The debugger does not attach. The Bun debug adapter needs a Node.js interpreter: set one in Settings → Languages & Frameworks → Node.js. If attaching still fails, the console reports it and continues without the debugger; switch the debugger off and on to retry.
A name "is not available … Restart Runtime". The file was loaded before the console could expose its non-exported names (see above). Restart Runtime.
The status line asks to Restart Runtime after an edit. A file imported by your context file changed; the modules that use it still hold the old version. Restart to load the new code.
The console is stuck on JavaScript is busy. Synchronous code is still running. Click ↻
Restart Runtime.
import … with { … }) are not supported yet.The plugin starts a Bun process with a small bootstrap script stored in the IDE's system folder
(nothing is written to your project) and talks to it over a local socket protected by a one-time
token. Console input is prepared in the IDE with WebStorm's JavaScript parser (import statements
and repeated declarations are rewritten so that they work in a REPL) and evaluated with Bun's
node:repl in the process's global scope. File contexts are read with Bun's transpiler to learn
their exports without running them; modules run through Bun's normal module loader on first use.
The debugger is WebStorm's own Bun debugger attached to the console's process, and paused-frame
evaluation uses the IDE's debugger API.
See docs/development.md for building, testing, running a sandbox IDE and the release checklist.
MIT © Petro Borshchahivskyi
The Run Selection icon is JetBrains' "Run and Select" icon from intellij-community, used under the Apache 2.0 license.