Repository navigation
fix(vscode): keep Rslint healthy when rstack.config has no define.lint() - #94
Merged
Merged
Conversation
rstack's lint shim (dist/rslintConfig.js) calls process.exit(1) when the Rstack config defines no lint configuration. The editor's lint worker evaluates that shim in-process, so a formatting-only rstack.config.* killed the worker mid-transaction and took the Go server and the language client transport down with it: "No lint configuration found" followed by connection-disposed and server-restart errors on every TypeScript file. The bridged worker now builds its ConfigModuleHost with a loadFresh wrapped by withProcessExitAsThrow: during module evaluation, process.exit throws an error tagged RSTACK_CONFIG_PROCESS_EXIT, which lands as a failed load result. ConfigTransactionAdapter classifies that code as a new `unconfigured` verdict on rstack/rslintConfigDependency, beside `missing` and `plugin`. The editor reports `running` with the detail `no define.lint() in rstack.config.ts`, logs one info line per episode, and neither polls, crashes nor warns. Adding define.lint() later is picked up by the same worker through the bridged config watcher, without a restart. Native runtimes are untouched. Adds the rstack-fmt-only E2E fixture and suite, unit coverage for the wrapper, the verdict and the editor state, and records the verdict and the lint-only shim behaviour in packages/vscode/AGENTS.md. Closes #93
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
2 tasks done
fi3ework
added a commit
that referenced
this pull request
Oct 10, 2026
…95) Follow-up to #94 (#93). A bridged lint runtime whose root rstack.config.* has no define.lint() reported `running` with a detail, which the status bar hover rendered as a green check beside Rslint with the reason only in the icon tooltip. The status bar's word for "this tool has no configuration here" is `not-detected`, so the `unconfigured` verdict now maps to `{ kind: 'not-detected', detail }` and the reason is shown as a hover notice row. - `StackState['not-detected']` gains an optional `detail`; only a runtime-level "nothing configured" verdict sets it, detection never does, so every other hover is unchanged. - The status bar spells out the `not-detected` detail; one shared `stackStateDetail` replaces the two identical switches in the shell and the lint fold. - `liveRslintStatus` / `reportLive` (renamed from `running*`) keep the advisory-wins precedence; the worker stays up, no poll, no toast. - Fold: an unconfigured-only folder stays `not-detected` with its reason; a healthy native runtime beside it wins. - AGENTS.md adaptation 7 and the lint-shim gotcha record the design, including that the verdict lives with the runtime (an idle folder reads `running: idle` until a document opens).
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A root
rstack.config.*with onlydefine.fmt()lights the lint stack (by design: the extension never reads the Rstack config itself). rstack's lint shim then callsprocess.exit(1)because it finds nodefine.lint(), and since the editor-shipped lint worker evaluates that shim in-process, the worker died mid-rslint/loadConfigsand took the Go server and the language-client transport with it. That is the "No lint configuration found" → connection-disposed → server-restart cascade in #93.Behaviour for a formatting-only project: Rslint still starts (the shim is the only thing that can decide), reports
runningwith a detail, logs oneinfoline, and produces no diagnostics, no toast, nocrashed, and no 60-second dependency poll. Addingdefine.lint()later is picked up by the same worker through the existing bridgedrstack.config.*watcher, without a restart. Native runtimes build theirConfigModuleHostexactly as before.Why not "don't start Rslint at all": the extension cannot know whether
define.lint()exists without evaluating the config, and a text probe is forbidden (AGENTS.md) and wrong under shared config layers. The shim's refusal is currently expressed only asprocess.exit(1); once rstack exports a marker or throws a typed error instead, the wrapper can go and the editor can classify by contract.Known trade-offs, recorded in
packages/vscode/AGENTS.md:process.exitduring a bridged config load (including one from the user's own config) is classifiedunconfigured. With rstack 0.8.2 the shim's refusal is the only exit in its import graph. A tighter check (exit code 1 + caller is the shim path) is possible as a follow-up.define.lint()has committed, removing it makes Go keep the last-good catalog while the status saysno define.lint();rs lintwould refuse.No lint configuration found…line and Go'sSkipped config …line still reach the Rslint Output channel beside ourinfoline.Evidence
Rstack fmt-only configE2E suite, run againstdist/built from the pre-fix source, fails with the issue's error:pnpm lint✓ ·pnpm test:unit365 passed, 0 failed · lint E2E (Rstack fmt-only config,Missing config dependency,Rstack lint bridge,JS config tests) allExit code: 0on macOS withVSCODE_CLI=1. The fmt-only suite asserts nocrashedstate, no diagnostics, no warnings, then addsdefine.lint()and assertsno-debuggerappears from the same lint-worker pid.define.fmt()-only project (rstack 0.8.2): status bar hover showsrunning — no define.lint() in rstack.config.ts, the Output channel has the single info line and no connection-disposed or restart errors; uncommentingdefine.lint(...)and saving produces the diagnostic without a restart.Merge Danger
Door: two-way
Revert restores the previous behaviour; no settings, protocol versions or published surfaces change. The new
unconfiguredverdict is editor-internal (worker ↔ extension host).Blast Radius: lint-bridged
Only bridged lint runtimes (a root
rstack.config.*without a tool-nativerslint.config.*) take the new path, and only when the shim refuses. Native Rslint runtimes, Rstest and fmt are untouched.Related Links
process.exit(1)on a missing lint configuration (fix(lint): report missing lint configuration rstack-cli#493, discussed in rs test / rs lint run with an empty config when define.test() / define.lint() is missing: intended or an oversight? rstack-cli#490); a follow-up there to export a marker or throw a typed error instead would let the editor drop the wrapper.Checklist