Repository navigation
Conversation
🦋 Changeset detectedLatest commit: cfc7723 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
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 |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
✅ 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.
big-pickle (free) | 𝕏
There was a problem hiding this comment.
🟡 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
|
@pullfrog review |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
- Editor configuration protocol v1 — Adds
editorConfigurationenvelope support toconfigurePlugin, with normalized parsing, resource limits, and mutual exclusivity with legacy replacement; mergesextraTagsinto project tags case-sensitively with deduplication. - Configuration state management — Introduces
EditorConfigurationManagerand extendsProjectConfigurationManagerto track dynamic configuration state (editor vs legacy), applying overlays to the project base and handling last-kind-wins across sources. - tsserver integration — Updates
StyledPluginto coordinate editor/project configuration lifecycle, recover project base fromcompilerOptions.plugins(with resilience if reading fails), and handle pre-project payloads correctly. - Public API and docs — Exports
EDITOR_CONFIGURATION_PROTOCOL_VERSIONand 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.
big-pickle (free) | 𝕏



Summary
This PR introduces version 1 of 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 basetagslist for integration-specific tags. Project configuration remains available for project-specific choices, while integration defaults can stay with the integration.The implementation:
tags,validate,lint, andemmetsettings as the base, then appends normalized editor tags;ProjectService;configurePluginpayloads;EDITOR_CONFIGURATION_PROTOCOL_VERSIONfrom@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
configurePluginpayload. The first places integration setup in each user'stsconfig.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 resetsvalidate,lint, andemmetsettings.The new envelope provides a separate additive path that preserves the project's choices:
{ "editorConfiguration": { "protocolVersion": 1, "source": "example-editor.css-templates", "extraTags": ["globalStyle", "styledNative"] } }sourceidentifies the integration, but does not act as an allowlist or a separate overlay key. Each valid payload replaces the previous overlay, including when the source changes, and an emptyextraTagsarray clears it.Configuration behavior
editorConfigurationmarker is treated only as an editor envelope. If it is invalid, the current dynamic state remains unchanged.PluginCreateInfo.config; the project base is recovered fromcompilerOptions.pluginsbefore applying an overlay.Limits and resilience
To keep per-request tag matching bounded, the protocol accepts a non-empty source of at most 128 UTF-16 code units, up to 64 tags, 256 code units per raw tag, and 4,096 across all raw tags. An over-limit update is left unapplied as a whole. Parsing and merging happen only when configuration changes, and repeated normalized payloads do not clear caches.
Editor envelopes and legacy runtime payloads are normalized before shared state changes. Malformed values are contained at the tsserver boundary, logs omit source and tag text, and dynamic state is scoped to one
ProjectService. The scaling suite and benchmark cover the maximum legal list with a match in the last position.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.
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 the protocol version constant and 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
Local verification includes lint, type checking, unit and scaling tests, benchmarks, the TypeScript 5.0/5.9/6.0 tsserver matrix, and package runtime, declaration, and contents checks.
The default release-comparison suite reports 70 of 70 cases unchanged from 1.1.1.
The Node 14.21.3 and unsupported-TypeScript smoke tests remain CI-only. It would be helpful to have the release workflow wait for those jobs and the full TypeScript matrix before protocol v1 is published.
Release order
This is a backward-compatible minor capability. To make adoption predictable, host integrations can enable settings based on protocol v1 after a plugin release includes it, with the final integration artifact checked to confirm that it contains the updated plugin.