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
2 changes: 1 addition & 1 deletion packages/vscode/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ One extension replacing the standalone `rstack.rslint` and `rstack.rstest` exten

1. **Shell activation** — stacks never self-activate; `register()` returns fast and never blocks on starting a server/worker.
2. **Namespace** — everything user-visible is `rstack.*`. Legacy `rslint.*` / `rstest.*` names appear only in the migration mapping. Command IDs were renamed without aliases (breaking old keybindings was an accepted cost).
3. **Resolve-from-project** — no tool binaries or tool packages in the VSIX; everything resolves from the user's project so the editor runs the CLI's exact versions. Version floors surface as a status, never a crash. All cooperating lint pieces (binary, config loader, plugin host) must come from one resolution root.
3. **Resolve-from-project** — no tool binaries or tool packages in the VSIX; everything resolves from the user's project so the editor runs the CLI's exact versions. Version floors surface as a status, never a crash. All cooperating lint pieces (binary, config loader, plugin host) must come from one resolution root. Enforced by lint: `@typescript-eslint/no-restricted-imports` in the root `rstack.config.ts` rejects any non-type import of `@rslint/core`, `@rstest/core`, `rstack` or `jiti` under `src/` — types only at compile time, runtime modules through explicit project paths.
4. **Status aggregation** — stacks own no UI chrome; they report to the shell's single status bar item, which always exists. In CI the test stack's `MasterLogger` also mirrors every entry to stderr (`RSTACK_E2E_MIRROR_LOGS=1`, set by `e2e/rstest/runTest.ts`) — the output channel is unreadable there; rationale in `stacks/test/logger.ts`.
5. **Worker-cwd decoupling** (test) — a project's cwd is explicit, not derived from the config file path; for native configs behavior stays byte-identical to upstream.
6. **Node runtime selection** (lint, test, fmt) — the Node a project-loading child process runs on is a **User Node runtime** chosen by the extension against one uniform floor, never assumed from PATH; the recovery path is the user's own shell, and the dividing line is the **load bound** (terms in CONTEXT.md; the full rule and rationale in `docs/adr/0001-node-runtime-selection.md`). All three callers — the lint worker, the rstest worker and the `rs fmt --lsp` server — take the decision from the one shared module (`shared/nodeResolution.ts`) and share one escape hatch, the resource-scoped `rstack.nodeExecutable` (`shared/nodeExecutableSetting.ts`); each appends its own consequence to the shared preflight message.
Expand Down
32 changes: 32 additions & 0 deletions rstack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,38 @@ define.lint(async () => {
'@typescript-eslint/no-require-imports': 'off',
},
},
{
// Resolve-from-project (packages/vscode/AGENTS.md, adaptation #3): the
// extension ships no tool packages, so extension source may only take
// *types* from them at compile time. Runtime modules come from the
// user's project through explicit paths — a static value import would
// bundle or `require()` the wrong copy.
files: ['packages/vscode/src/**/*.ts'],
rules: {
'@typescript-eslint/no-restricted-imports': [
'error',
{
patterns: [
{
group: [
'@rslint/core',
'@rslint/core/*',
'@rstest/core',
'@rstest/core/*',
'rstack',
'rstack/*',
'jiti',
Comment thread
fi3ework marked this conversation as resolved.
'jiti/*',
],
allowTypeImports: true,
message:
'Extension source may only import types from tool packages; load the runtime module from the project (see AGENTS.md, resolve-from-project).',
},
],
},
],
},
},
{
languageOptions: {
parserOptions: {
Expand Down