Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@
"args": [
"--extensionDevelopmentPath=${workspaceFolder}/packages/vscode",
"--disable-extensions",
// An isolated, auto-created profile, so personal user settings
// (formatters, format-on-save, keybindings) cannot leak into the
// playground. `--user-data-dir` would be the stronger isolation, but
// the extension-host debugger strips it; `--profile` is the supported
// mechanism for debug launches.
"--profile=rstack-playground",
// A fresh profile would otherwise prompt for workspace trust and greet
// with the welcome tour on every first launch.
"--disable-workspace-trust",
"--skip-welcome",
"--skip-release-notes",
"--disable-updates",
"${workspaceFolder}/packages/vscode/${input:playgroundTarget}"
],
"outFiles": ["${workspaceFolder}/packages/vscode/dist/**/*.js"],
Expand Down
6 changes: 5 additions & 1 deletion .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@
"background": {
"activeOnStart": true,
"beginsPattern": "build started\\.\\.\\.",
"endsPattern": "built in"
// Not "built in" — that line fires once per target, and the tiny
// worker bundle finishes seconds before the extension bundle, which
// released the F5 launch against a half-written dist/. This line is
// printed once, after every target completed.
"endsPattern": "build completed"
}
},
"presentation": {
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ The extension takes its configuration from five sources. The tool-native configs
| `rslint.config.*` | **Supported.** Diagnostics, quick fixes and the language server, all resolved from the `@rslint/core` installed in your project. |
| `rstest.config.*` | **Supported.** Test discovery, run and debug, watch mode, coverage and snapshot updates in the Test Explorer. |
| `define.test()` in `rstack.config.*` | **Supported.** Tests run through the same config shim `rs test` uses, so the editor and the CLI resolve the config identically. |
| `define.fmt()` in `rstack.config.*` | **Planned.** Detected and reported in the status bar; formatting itself arrives next, first over `rs fmt --stdin-filepath` and later over an `rs fmt` language server. |
| `define.fmt()` in `rstack.config.*` | **Supported.** Document formatting through the project-local `rs fmt --stdin-filepath`, resolving the config the same way the CLI does; an `rs fmt` language server is the longer-term path. |
| `define.lint()` in `rstack.config.*` | **Planned.** Linting a project configured only through `rstack.config.*` needs upstream changes in Rslint and rstack-cli before the editor can evaluate it correctly. `rs lint` on the command line is unaffected. |

## License
Expand Down
2 changes: 1 addition & 1 deletion packages/vscode/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ One extension replacing the standalone `rstack.rslint` and `rstack.rstest` exten

- The lint × `rstack.config.*` bridge was built and deliberately removed: a partial editor-side bridge gave wrong results, and a correct one needs upstream work first. `TODO(rstack-bridge)` markers carry the plan. Do not reintroduce a partial bridge.
- The test × `rstack.config.*` bridge stays thin on purpose: it points the upstream machinery at rstack's shipped shim and lets the shim interpret the config inside the worker, same as the CLI. Never re-implement rstack config semantics in the extension.
- The fmt stack is a stub on purpose. The MVP will spawn `rs fmt --stdin-filepath` with cwd = the config directory (forced by rs fmt's cwd-only config resolution); the endgame is an upstream LSP, so do not add a warm-process middle tier or "fix" the stub into an error state.
- The fmt stack is a spawn-per-request `rs fmt --stdin-filepath` MVP. Its cwd is the governing config directory because rs fmt resolves config from cwd only, and formatting errors are log-only by design. The endgame is an upstream LSP, so do not add a warm-process middle tier.
- `projectModules.ts` has no cache-invalidation hook and restart must not grow one. Node's ESM registry is keyed by resolved URL and process-lifetime, so clearing the local memo hands back the identical module object (verified); a `?epoch=` query does reload the entry but relative specifiers inside it do not inherit the query, yielding a fresh entry over stale dependencies. In-place reinstalls under an unchanged path need a window reload — say so, don't fake it.
- The VSIX is platform-targeted for exactly one reason: the test stack's AST collection loads a native parser binding. Do not add another native dependency — it multiplies the release matrix.

Expand Down
11 changes: 6 additions & 5 deletions packages/vscode/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Rstack for VS Code

One extension for the whole [Rstack](https://rstack.rs) toolchain: [Rslint](https://github.com/web-infra-dev/rslint) linting, [Rstest](https://github.com/web-infra-dev/rstest) testing, and [rstack-cli](https://github.com/rstackjs/rstack-cli) support (coming soon). It replaces the standalone `rstack.rslint` and `rstack.rstest` extensions.
One extension for the whole [Rstack](https://rstack.rs) toolchain: [Rslint](https://github.com/web-infra-dev/rslint) linting, [Rstest](https://github.com/web-infra-dev/rstest) testing, and [rstack-cli](https://github.com/rstackjs/rstack-cli) support. It replaces the standalone `rstack.rslint` and `rstack.rstest` extensions.

## Installation

Expand All @@ -13,7 +13,7 @@ The extension ships no tool binaries: `@rslint/core`, `@rstest/core` and `rstack

- **Linting (Rslint)** — diagnostics, quick fixes and auto-fix on save via Rslint's language server.
- **Testing (Rstest)** — a Test Explorer tree built from your test files: run or debug individual tests, suites or files; the tree stays in sync as files change; failed tests show up as editor diagnostics.
- **rstack-cli** — detected today, integration lands in upcoming releases, starting with formatting.
- **rstack-cli** — document formatting through the project-local `rs fmt` CLI.
- **One status bar item** — a single `Rstack` entry shows which tools are active in the current workspace and why.

## Detection
Expand All @@ -38,7 +38,7 @@ The project-resolved packages are checked against a support matrix at runtime; a
| -------------- | --------- |
| `@rslint/core` | `>=0.7.2` |
| `@rstest/core` | `>=0.6.0` |
| `rstack` | `>=0.3.2` |
| `rstack` | `>=0.3.5` |

## Auto-fix on save (Rslint)

Expand Down Expand Up @@ -94,8 +94,9 @@ All settings live under the unified `rstack.*` namespace. There are no `rslint.*
| `rstack.rstest.debuggerAddress` | — | Debugger address. |
| `rstack.rstest.terminalShellPath` | — | Shell used by **Run in Terminal**. |
| `rstack.rstest.terminalShellArgs` | `[]` | Shell args for **Run in Terminal**. |
| `rstack.fmt.enable` | `true` | Enable/disable the formatter integration (upcoming). |
| `rstack.fmt.suggestDefaultFormatter` | `true` | Offer to set `editor.defaultFormatter` once rstack-cli is detected. |
| `rstack.fmt.enable` | `true` | Enable/disable the formatter integration. |

To use `rs fmt` as the formatter for supported documents, opt in through your VS Code settings: `"editor.defaultFormatter": "rstack.rstack"`. The extension never changes `editor.defaultFormatter` itself.

## Migrating from the standalone extensions

Expand Down
9 changes: 1 addition & 8 deletions packages/vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -334,14 +334,7 @@
"type": "boolean",
"default": true,
"scope": "window",
"markdownDescription": "Enable the `rs fmt` document formatter for detected workspace folders. Requires `#rstack.enable#`. This is a window-level kill switch; which folders are formatted is decided by detection. Phase 2 — the formatter is not registered yet."
},
"rstack.fmt.suggestDefaultFormatter": {
"order": 1,
"type": "boolean",
"default": true,
"scope": "resource",
"markdownDescription": "Offer a one-time prompt to set Rstack as the workspace `editor.defaultFormatter` when `rs fmt` is detected. The extension never writes `editor.defaultFormatter` without confirmation."
"markdownDescription": "Enable the `rs fmt` document formatter for detected workspace folders. Requires `#rstack.enable#`. This is a window-level kill switch; which folders are formatted is decided by detection."
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/vscode/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type Gate =
*/
class ExtensionShell {
readonly #channels = new Channels();
readonly #statusBar = new StatusBar();
readonly #statusBar = new StatusBar(this.#channels.shell);
readonly #detection: DetectionService;
readonly #controllers = new Map<StackId, StackController>();
readonly #subscriptions: vscode.Disposable[] = [];
Expand Down
6 changes: 3 additions & 3 deletions packages/vscode/src/shared/vendored/loadRstackConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
// explicit-path config loader plus adapter exports, rslint accepting per-root
// fallback config candidates on `rslint/configRefresh`, and a generic
// evaluator-module seam shared by the config host and plugin workers). The
// loader is kept for the phase-2 fmt stack (evaluating `define.fmt()`) and
// possible future status refinements; today only
// `nativeTypeStrippingAvailable` is consumed.
// formatter deliberately leaves `define.fmt()` evaluation to the CLI. This
// copy remains for the Rslint jiti preflight's `nativeTypeStrippingAvailable`
// probe and for direct loader unit coverage.
//
// Vendored from rstackjs/rstack-cli `packages/rstack/src/config.ts`
// (origin/main @ 6494ba2, rstack@0.3.2). Only three things differ from upstream:
Expand Down
5 changes: 3 additions & 2 deletions packages/vscode/src/shared/versionCheck.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ import { readPackageJson } from './packageResolve';
* - `@rslint/core >= 0.7.2` — first version whose package exports
* `./config-loader` and `./eslint-plugin`.
* - `@rstest/core >= 0.6.0` — the existing `MIN_CORE_VERSION` upstream.
* - `rstack >= 0.3.2` — first release containing `rs fmt --stdin-filepath`.
* - `rstack >= 0.3.5` — first release with the full supported config and
* formatter surface.
*/
export const SUPPORT_MATRIX = {
'@rslint/core': '>=0.7.2',
'@rstest/core': '>=0.6.0',
rstack: '>=0.3.2',
rstack: '>=0.3.5',
} as const;

export type SupportedPackage = keyof typeof SUPPORT_MATRIX;
Expand Down
Loading