Skip to content

feat: support editor-provided styled template tags - #43

Open
usercao wants to merge 9 commits into
mainfrom
update
Open

usercao wants to merge 9 commits into
mainfrom
update

Conversation

@usercao

@usercao usercao commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

This PR introduces an editor configuration protocol for appending tagged-template names at runtime. The protocol is intended for third-party editor extensions, language-server adapters, and other tsserver hosts across platforms, without tying the contract to VS Code or vscode-styled-components.

An integration that ships or loads this plugin can use the protocol to expose its own setting for compatible CSS tagged-template APIs and pass those tag names to tsserver. This can spare users from installing the package in each project, adding a plugin entry to every tsconfig.json, or copying the full base tags list for integration-specific tags. Project configuration remains available for project-specific choices, while integration defaults can stay with the integration.

The implementation:

  • keeps project tags, validate, lint, and emmet settings as the base, then appends normalized editor tags;
  • supports configuration sent before or after project creation and shares the latest valid dynamic state within one tsserver ProjectService;
  • preserves the full-replacement behavior of legacy configurePlugin payloads;
  • refreshes diagnostics for every live project when effective runtime settings change;
  • exports the protocol types from @styled/typescript-styled-plugin/api and documents the host contract.

Motivation

Without an additive protocol, a third-party integration has two available paths: ask users to install and configure the plugin in each project, or send a normal configurePlugin payload. The first places integration setup in each user's tsconfig.json. The second is not a good fit for an additive setting because tsserver treats the payload as the complete plugin configuration. For example, { tags: ["globalStyle"] } replaces project-defined tags and resets validate, lint, and emmet settings.

The new envelope provides a separate additive path that preserves the project's choices:

{
  "editorConfiguration": {
    "extraTags": ["globalStyle", "styledNative"]
  }
}

Each valid payload replaces the previous overlay, and an empty extraTags array clears it.

Configuration behavior

  • Base tags remain first and retain matching priority. Editor tags are trimmed and deduplicated in insertion order with case-sensitive comparison.
  • Non-string and empty entries are skipped. A non-empty array with no valid entries preserves the current dynamic state; only a literal empty array clears the overlay.
  • A payload with an editorConfiguration marker is treated only as an editor envelope. If it is invalid, the current dynamic state remains unchanged.
  • Legacy replacement and editor overlay are mutually exclusive. The most recent valid kind takes effect, and a later editor envelope rebuilds from the project base.
  • Payloads received before project creation are handled through PluginCreateInfo.config; the project base is recovered from compilerOptions.plugins before applying an overlay.
  • Extra tags use the same matching and parsing rules as project tags. Built-in special names retain their parsing behavior; custom names such as globalStyle get ordinary component parsing, not global stylesheet parsing.

Resilience

Editor envelopes and legacy runtime payloads are normalized before shared state changes. Malformed values are contained at the tsserver boundary, logs omit tag text, and dynamic state is scoped to one ProjectService. Parsing and merging happen only when configuration changes, and repeated normalized payloads do not clear caches or refresh diagnostics.

If the editor marker cannot be read safely, the payload follows legacy normalization rather than being classified as an invalid editor envelope. If a host throws while the plugin reads project compiler options, the plugin records the problem and falls back to the default project base so activation can continue.

Adapter documentation

The public adapter contract is documented in Editor integration protocol, aligned with this PR as a shared reference for third-party editor extensions, language-server adapters, and other compatible tsserver hosts. The README and usage guide link to it. Host-specific notes, including those for VS Code, describe individual integrations without limiting the scope of the protocol.

It covers payload validation, configuration state, replay, and adapter verification. The payload builder explicitly distinguishes invalid input from an empty array, so rejected entries cannot accidentally clear an existing overlay.

Compatibility

For users whose host does not send the new envelope, default, project, and legacy runtime configuration retain their existing behavior. The package root factory remains compatible with 1.0.1, and the public API adds only two protocol types. Real tsserver tests run against TypeScript 5.0, 5.9, and 6.0; TypeScript 4.9 retains the existing unsupported-host behavior. TypeScript 7 remains outside this tsserver-plugin protocol.

Testing

corepack yarn verify passes, including formatting, lint, type checking, unit and scaling tests, default tsserver E2E tests, and package runtime, declaration, and contents checks. The TypeScript 5.0/5.9/6.0 tsserver matrix also passes.

The documentation's payload builder passes strict TypeScript checking and 12 behavior cases checked against the plugin implementation, including explicit clearing and preservation of state for invalid input. Documentation links and anchors have also been checked.

The TypeScript 4.9 non-activation smoke test passes locally. The Node 14.21.3 smoke test remains a CI gate because the local arm64 host cannot execute the official darwin-x64 binary. Making the release workflow wait for those jobs and the full TypeScript matrix belongs to a separate workflow PR.

Release order

This is a backward-compatible minor capability. To make adoption predictable, host integrations can enable settings after a plugin release includes it, with the final integration artifact checked to confirm that it contains the updated plugin.

Copilot AI balanced review requested due to automatic review settings October 24, 2026 08:11
@changeset-bot

changeset-bot Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 2aa5cf1

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@styled/typescript-styled-plugin Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

This adds the version 1 editor configuration protocol cleanly: strict envelope/version/source checks, normalization (dedupe/trim, non-string entries skipped with logs), resource limits enforced with reportResourceLimits, and editor extraTags are appended on top of project config. Legacy configurePlugin payloads keep full-replacement behavior. EditorConfigurationManager and ProjectConfigurationManager wiring is exception-safe (logging best-effort, no exceptions leak into tsserver), handles before/after project creation, and shares state correctly across projects in one host. Exports/types/docs/changeset/tests all look consistent. Ready to merge as-is.

Pullfrog  | View workflow run | Using big-pickle (free) | 𝕏

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Clean-checkout typechecking is blocked, revoked configuration Proxies can abort activation, and shared-listener lifecycle memory coverage is missing.

3 open issues
What changed in this PR

Adds protocol v1 so editor integrations can append styled-template tags without replacing project settings, while preserving legacy runtime configuration behavior.

Changes:

  • Introduces bounded editor-tag overlays shared within a tsserver ProjectService.
  • Exports protocol types and a version constant, with integration documentation.
  • Adds configuration, lifecycle, package API, and performance coverage; updates dependencies.
File Description
yarn.lock Records dependency updates.
test/​unit/​tsserver-plugin.test.ts Tests configuration arrival order, sharing, and isolation.
test/​unit/​plugin-configuration.test.ts Tests normalization, overlays, limits, and hostile inputs.
test/​performance/​template-language-service.bench.ts Benchmarks matching the last allowed editor tag.
test/​performance/​scaling-check.ts Adds maximum-tag matching checks.
test/​package-api/​tsconfig.json Includes the CommonJS API consumer in typechecking.
test/​package-api/​runtime.ts Checks the exported protocol version.
test/​package-api/​runtime-esm-consumer.mjs Checks the protocol version through ESM imports.
test/​package-api/​consumer.ts Exercises public protocol types.
test/​package-api/​consumer-api.cts Exercises the CommonJS protocol API.
test/​e2e/​scenarios/​plugin-lifecycle.test.ts Tests editor overlays through real tsserver requests.
test/​e2e/​fixture-paths.ts Registers the editor-configuration fixture.
test/​e2e/​editor-configuration-project-fixture/​tsconfig.json Defines project settings for overlay tests.
test/​e2e/​editor-configuration-project-fixture/​main.ts Provides the fixture’s source file.
src/​tsserver/​tsserver-plugin.ts Restores project bases and coordinates dynamic configuration.
src/​tsserver/​tsserver-logger.ts Contains host logging failures.
src/​tsserver/​plugin-identity.ts Adds the package-name constant.
src/​tsserver/​editor-configuration.ts Implements protocol parsing, shared state, and tag merging.
src/​index.ts Scopes shared configuration to each ProjectService.
src/​configuration/​plugin-configuration.ts Defines protocol types and hardens configuration copying.
src/​api.ts Exports protocol types and version.
package.json Updates runtime and development dependencies.
docs/​usage.md Explains editor overlays and replacement behavior.
docs/​tsserver-host.md Documents project-base recovery during activation.
docs/​maintenance.md Adds protocol testing guidance.
docs/​architecture.md Specifies configuration state and lifecycle invariants.
.changeset/​quiet-tags-overlay.md Declares the additive capability as a minor release.

Review effort: Balanced

Comment thread test/package-api/tsconfig.json Resolved
Comment thread src/tsserver/editor-configuration.ts Resolved
Comment thread src/tsserver/tsserver-plugin.ts Resolved
@usercao

usercao commented Oct 24, 2026

Copy link
Copy Markdown
Collaborator Author

@pullfrog review

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

  • Editor configuration protocol v1 — Adds editorConfiguration envelope support to configurePlugin, with normalized parsing, resource limits, and mutual exclusivity with legacy replacement; merges extraTags into project tags case-sensitively with deduplication.
  • Configuration state management — Introduces EditorConfigurationManager and extends ProjectConfigurationManager to track dynamic configuration state (editor vs legacy), applying overlays to the project base and handling last-kind-wins across sources.
  • tsserver integration — Updates StyledPlugin to coordinate editor/project configuration lifecycle, recover project base from compilerOptions.plugins (with resilience if reading fails), and handle pre-project payloads correctly.
  • Public API and docs — Exports EDITOR_CONFIGURATION_PROTOCOL_VERSION and editor configuration types from ./api, documents the protocol in usage/architecture/tsserver-host/maintenance docs.
  • Tests and fixtures — Adds e2e scenarios for appending/clearing editor tags, pre-project payloads, kind switching, and unit/probe coverage for lifecycle behavior.

Pullfrog  | View workflow run | Using big-pickle (free) | 𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes (since prior Pullfrog review)

  • Completed editor configuration lifecycle — Hardened activation around revoked/hostile configs (e.g. guarded Array.isArray access) and corrected legacy activation paths so overlays/legacy replacements behave correctly across reloads and project creation order.
  • Memory/lifecycle coverage — Added test/unit/editor-configuration-lifecycle.probe.ts exercising weak-reference cleanup for discarded projects/listeners with GC and a surviving-project control; extended lifecycle tests.
  • Package API typecheck scoping — Removed test/package-api/consumer-api.cts from the source typecheck tsconfig so clean typechecking works before build (post-build consumers still covered).
  • CI/release gates and docs — Updated CI/release/docs/changeset as part of completing the protocol lifecycle.

The incremental changes address all previously flagged issues. Existing behavior remains backward compatible and tests/fixtures look consistent.

Pullfrog  | View workflow run | Using big-pickle (free) | 𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

Changes since the prior pullfrog review (1911d3e), one test-tooling commit:

  • Enlarged N for coarse-clock text checks — Raises the fixture size from 6,000 to 24,000 for the four substitution and escape cases whose N timing sits near the 1 ms CPU clock quantum, so a quantized 0.000ms N sample no longer makes the ratio unmeasurable.
  • Threaded a per-case N through the check factory — Adds an optional n to TextCheckCase and defineTextCheck, defaulting to SUBSTITUTION_CHECK_N so untouched cases keep their size.

Filtered runs of all four affected checks pass with ratios from 3.3 to 4.5, inside MIN_PLAUSIBLE_RATIO and SCALING_THRESHOLD, and finish well under the per-check deadline.

Pullfrog  | View workflow run | Using big-pickle (free) | 𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

Changes since the prior pullfrog review (cb08bf8), all in test tooling:

  • E2E cleanup timeout headroom — Derives the e2e hookTimeout from TSSERVER_RESPONSE_TIMEOUT_MS plus 15 s so onTestFinished/afterAll cleanup can surface the harness's process-exit timeout instead of Vitest's generic hook timeout.
  • Bounded response timeout — Caps the parsed response timeout at MAX_TIMER_DELAY_MS - E2E_TIMEOUT_HEADROOM_MS, keeping the derived hook and test timeouts within Node's maximum timer delay.
  • Config extraction — Exports e2eTimeoutMs, e2eTestConfig, e2eProjectConfig, and vitestConfig so a unit test can assert the e2e project wiring.
  • Coverage and docs — Adds unit tests for the capped parser and the Vitest project wiring, and documents the hook-timeout relationship in docs/maintenance.md.
  • Changeset — Adds a patch changeset for the cleanup-hook headroom.

Verification: yarn typecheck, the two new unit files, oxlint, and oxfmt --check pass. Vitest's runner uses runner.config.hookTimeout for onTestFinished, so the raised value governs per-test server cleanup as intended.

Pullfrog  | View workflow run | Using big-pickle (free) | 𝕏

@quantizor quantizor left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, the core is right and I want it in. Appending editor tags on top of the project's tags is the fix, and the tsserver lifecycle handling is solid.

I installed the packed build in VS Code and stepped through sending editor tags, clearing them, sending a legacy payload, and sending tags again. Each state applied correctly, completion and hover work inside the added tag, and untagged templates stay untouched. I also compared it against main with a real tsserver on outline/outline (1,033 styled templates) using typing, completion, and file switch traces. There's no measurable change in latency, cold start, or heap, and no leak.

Before it ships as a minor, please cut it down, since src/api.ts becomes public contract on publish:

  • Drop protocolVersion, EDITOR_CONFIGURATION_PROTOCOL_VERSION, and source. The editorConfiguration key is enough of a discriminator, and a version can come when a second shape exists.
  • Drop the tag count and length caps. Skip bad entries like non-strings are skipped today.
  • Replace the deep clone with a one-level copy, and drop the proxy and gc probe tests, FinalizationRegistry, and deactivate.
  • Keep the previous overlay when every entry in an array is rejected. Only a real [] should clear.
  • Treat a differing project entry as a legacy replace only when its settings actually differ.
  • Call project.refreshDiagnostics() on each live project after a config change is applied. Today open files keep stale diagnostics until the next edit, because tsserver never emits projectsUpdatedInBackground after configurePlugin. Main has the same gap, but this PR is what makes runtime config changes a normal editor flow, so it matters now.
  • Note in the docs that an extra tag is only a match string, so globalStyle won't parse as a global stylesheet.
  • Move the dependency bumps, CI and release workflow changes, and the hook timeout changeset to separate PRs.

Then update the phase 7 spec to match this PR before the VS Code side is built.

@pullfrog

pullfrog Bot commented Oct 30, 2026

Copy link
Copy Markdown

The model never responded, so Pullfrog stopped this run after 2 minutes. The request went out but nothing came back. This is usually temporary, so re-trigger to try again.

Last agent output
timestamp=2026-10-30T03:45:30.357Z level=ERROR run=aef8aa01 message="stream error" providerID=opencode modelID=big-pickle session.id=ses_e752b84b9ffeMsP2yFQPWlmDqC small=false agent=build mode=primary error.error="AI_APICallError: Free usage limit reached. Free models work in OpenCode (https://opencode.ai); subscribe to OpenCode Go to keep going: https://opencode.ai/go"

Pullfrog  | Rerun failed job ➔ | View workflow run | via Pullfrog | Using big-pickle (free)

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes (since prior Pullfrog review)

  • Simplified editor configuration protocol — Removed protocolVersion, source, EDITOR_CONFIGURATION_PROTOCOL_VERSION, and resource limits from the protocol. The editorConfiguration key with extraTags is sufficient for discrimination. Bad entries (non-strings) are skipped; an empty array explicitly clears the overlay, while a non-empty array with all entries skipped preserves the previous overlay.
  • Diagnostics refresh on effective changes — EditorConfigurationManager now calls project.refreshDiagnostics() on each live project after applying effective configuration changes (deduplicated per project per update). Both legacy and editor updates refresh diagnostics when they actually change effective settings, and failures in individual projects are logged without affecting others.
  • Normalized diffing and safer legacy detection — Legacy configuration overrides are only treated as replacements when normalized settings actually differ; shared state comparisons use deep equality and avoid unnecessary notifications/caches/diagnostic refreshes.
  • Tightened config cloning and storage — Replaced deep cloning with one-level copies for lint/Emmet objects, removed FinalizationRegistry/gc probes/deep hostile input guards and related tests, and streamlined the configuration lifecycle.
  • Docs and tests updated — Documentation now clarifies extra tags are match strings only (no global stylesheet parsing mode), and tests/fixtures were updated to match the simplified protocol.

The latest commits address all points raised in the human review. No new issues found.

Pullfrog  | View workflow run | Using big-pickle (free) | 𝕏

@usercao

usercao commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator Author

@quantizor Thank you for the thoughtful review. I’ve added a public Editor integration protocol document, aligned with the current PR, as a shared reference for third-party editor extensions, language-server adapters, and other compatible tsserver hosts. The documentation links now point to this guide, with host-specific notes clearly separated from the common protocol.

It also clarifies payload construction so that an invalid non-empty array cannot accidentally become a request to clear the overlay.

When you have a chance, would you mind taking another look? I’d appreciate any further feedback.

@usercao
usercao requested a review from quantizor October 30, 2026 06:33

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ No critical issues. One documentation precision suggestion inline.

Reviewed changes

Changes since the prior pullfrog review (19eed88), one docs-only commit:

  • Added editor integration protocol guide — New docs/editor-integration.md defines the adapter contract for availability, payload shape, normalization, configuration state, lifecycle and replay rules, VS Code API v0 transport, and validation/release gates.
  • Documented VS Code configuration transport — docs/tsserver-host.md records verified ApiV0.configurePlugin, PluginManager map/replay, and projectsUpdatedInBackground behavior with source links.
  • Linked the guide from public docs — README, usage, and maintenance now point adapter authors to the new protocol guide.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using big-pickle (free) | 𝕏

Comment thread docs/editor-integration.md Resolved

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

Changes since the prior pullfrog review (6a5a38f), one docs-only commit:

  • Clarified tag parsing semantics — docs/editor-integration.md and docs/usage.md now state that extra tags are matched exactly like project tags, that the built-in special names (css, keyframes, createGlobalStyle, globalCss, injectGlobal) keep their parsing behavior when enabled through extraTags, and that only custom names such as globalStyle get ordinary component parsing. This matches getTagKind in src/virtual-document/styled-virtual-document-provider.ts, which selects parsing by the matched tag's AST name regardless of source.

This addresses the single open documentation finding from the prior review; no behavioral changes.

Pullfrog  | View workflow run | Using big-pickle (free) | 𝕏

@quantizor quantizor left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for turning this around so fast. This is close and I'd like to merge it after one small cleanup pass.

Everything from my last review that changes behavior is in. I packed the current code (810d4af only adds docs on top of the build I tested), installed it in a scratch project and walked VS Code through configure, resend, invalid, mixed, clear, legacy and back with no typing at all. Squiggles update about 300ms after each real change and no-ops leave things alone. On main nothing updates until you edit, so the refreshDiagnostics ask is resolved. A plain stdio tsserver client with no VS Code code gets the same states, so the editor neutral wording holds. The new parsing note is right too. createGlobalStyle added through extraTags parses as a global stylesheet and globalStyle parses as a component.

Perf against main on outline/outline shows no change in typing, completion, geterr or heap. Resends are actually cheaper now because no-ops skip the cache flush. Heap stays flat over 1000 sends and 60 open and close cycles.

What I'd still like before merge:

  • Drop the try/catch blocks around the config checks in editor-configuration.ts (hasOwn and parseEditorConfiguration) and the Object.keys block in isLegacyConfigurationOverride. That config is always parsed tsconfig JSON or a JSON configurePlugin payload, so it's a plain object and those reads can't throw. Keep the guard in the per-project apply loop since one bad project shouldn't leave the rest half updated, and keep the logging guards since the tsserver logger ends in fs.writeSync.
  • Which host are the getCompilerOptions and refreshDiagnostics guards for? In TS 5.0 and 5.9 getCompilerOptions is a plain getter and refreshDiagnostics only calls the host's event handler, and the only tests that throw there use hand built fakes. If there's a real host that needs them, add a comment naming it. Otherwise I'd drop them.
  • Replace the WeakRef listeners and registrations with a plain Set and remove a project when it closes. The registrations in tsserver-plugin.ts only feed a log line, so they can go.
  • Move the legacy path changes in plugin-configuration.ts to their own PR. That's the whole normalize try/catch, getArrayLength, the defineProperty lint keys and cloneConfigurationRecord. They may be fine but they aren't part of this protocol.
  • Remove the package-api tests that assert EDITOR_CONFIGURATION_PROTOCOL_VERSION is not exported. That name never shipped.

Small optional ones:

  • refreshDiagnostics runs once per project, and in TS 5.9 each call already emits an event for every open file. So 5 projects means 5 events for one change. Calling it once per ProjectService would be enough. tsserver coalesces the work so the cost is only about 1ms today.
  • "1 additional tags" in the applied log line.

@usercao

usercao commented Oct 31, 2026 •

Copy link
Copy Markdown
Collaborator Author

Thanks for the careful review and for testing the packed build. The cleanup is in 2aa5cf1:

  • Removed the try/catch blocks around the config checks. The per-project apply guard and logging guards stay.
  • Dropped the getCompilerOptions / refreshDiagnostics guards. I added them without a real host that needs them: in TS 5.0.4, 5.9.3 and 6.0.3 they are a plain getter and a single ProjectService call. The fake-only tests are gone too.
  • Replaced WeakRef with a plain Set, removed on project close, and deleted the registrations.
  • Moved the legacy changes to fix: normalize legacy configuration safely #49.
  • Removed the EDITOR_CONFIGURATION_PROTOCOL_VERSION assertions.
  • Optional: refreshDiagnostics() now runs once per ProjectService, and the log says 1 additional tag.

verify, the three TypeScript e2e runs and the 4.9.5 smoke pass locally. I didn't re-run the VS Code walkthrough or perf comparison, and I'm relying on CI for the Node 14 smoke.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

Changes since the previously reviewed commit 810d4af (one commit, 2aa5cf1):

  • Dropped leftover config-read guards — isLegacyConfigurationOverride, readProjectPluginConfiguration, and onConfigurationChanged now use the parsed configuration directly; the per-project apply loop and logging guards remain.
  • Replaced weak listeners with a strong Set — addListener wraps each project's close() once to remove all of that project's listeners and restore the original method, and the per-project registration registry in tsserver-plugin.ts is gone.
  • Refreshed diagnostics once per ProjectService — applyAndRefresh calls refreshDiagnostics() on one live project after all managers update, relying on tsserver's service-wide background update.
  • Moved legacy hardening out of scope — plugin-configuration.ts is back to main plus the two public editor types; copy-behavior tests and package-api assertions for the never-shipped protocol version constant are removed.
  • Updated docs, changeset, and lifecycle coverage — the docs and changeset match the close cleanup and per-service refresh, and new unit/e2e coverage exercises close/reopen and the single-refresh path.

Verification: targeted unit tests (78 passed), the full plugin-lifecycle e2e scenario (23 passed), and yarn compile all pass.

Pullfrog  | View workflow run | Using big-pickle (free) | 𝕏

@usercao
usercao requested a review from quantizor October 31, 2026 06:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants