Skip to content

LSP plugin restructure: rename to *-lsp, tiny setup skills, no-restamp shim (2.0.0) - #2

Merged
Cordedmink2 merged 14 commits into
mainfrom
refactor/lsp-only-plugin-rename
Jul 21, 2026
Merged

LSP plugin restructure: rename to *-lsp, tiny setup skills, no-restamp shim (2.0.0)#2
Cordedmink2 merged 14 commits into
mainfrom
refactor/lsp-only-plugin-rename

Conversation

@Cordedmink2

Copy link
Copy Markdown
Owner

Summary

Restructures both marketplace plugins to be lean LSP servers set up by a single, manually-run skill — and removes the per-machine schema-path re-stamp that setup previously required after every update. Breaking (2.0.0).

  • Renamed dataverse-customization-xmldataverse-xml-lsp and power-automate-cloud-flowcloud-flow-json-lsp (both bumped to 2.0.0).
  • Each plugin is now an LSP server + one tiny, no-description setup skill (/<plugin>:<plugin>-setup). The old auto-triggering skill and the /<plugin>:setup slash command are gone; editing guidance moved to each plugin's docs/guide.md.
  • No more re-stamp: a launcher shim (scripts/lsp-launch.mjs, referenced in .lsp.json with ${CLAUDE_PLUGIN_ROOT}) resolves the bundled schema at launch, so the committed .lsp.json is portable and setup need not be re-run after /plugin update or a repo move.
  • dataverse-xml-lsp keeps Validate-DataverseXml.ps1 as the CI/headless + pac wrapper-file (<forms>/<visualization>) validator; those wrapper files are validator-owned and deliberately not LSP-associated (the LSP would false-positive on the wrapper root).

Why

The plugins are fundamentally LSP servers; the fat auto-triggering skills and the fragile absolute-path stamping added friction. This makes setup one manual step, updates zero-touch, and keeps the schema references portable.

Migration (breaking)

  • Reinstall under the new ids: /plugin install dataverse-xml-lsp@dataverse-agent-plugins and /plugin install cloud-flow-json-lsp@dataverse-agent-plugins.
  • Update your enabledPlugins keys to the new ids.
  • Guidance that used to surface automatically now lives in each plugin's docs/guide.md.

Verification

  • Invoke-Pester plugins56 passed, 0 failed, 0 skipped (added: setup-skill frontmatter guard, install idempotency, XML shim-driven LSP smoke, wrapper-association guards for both the shim and the VS Code path).
  • Both Install-Plugin.ps1 self-checks pass; running them does not modify .lsp.json (portability proven from a moved copy).
  • Invoke-ScriptAnalyzer -Path plugins -Recurse -Settings ./PSScriptAnalyzerSettings.psd1 clean.
  • A launcher-shim feasibility spike proved runtime schema injection for both the JSON server and lemminx before it was productionized (recorded in the design spec).

Notes

  • Design + implementation plan: docs/superpowers/specs/2026-07-21-lsp-only-plugin-rename-design.md, docs/superpowers/plans/2026-07-21-lsp-plugin-rename-restructure.md.
  • Includes one pre-existing docs commit (8ba38b3, the power-automate retrospective spec) that this branch was based on; the two prior design specs are relocated under docs/superpowers/specs/ and marked historical/superseded.

Connor Parsons added 14 commits July 21, 2026 11:48
Reframe both marketplace plugins as LSP + tiny no-description setup
skill, rename dataverse-customization-xml -> dataverse-xml-lsp and
power-automate-cloud-flow -> cloud-flow-json-lsp, eliminate the
per-machine schema-path re-stamp (launcher shim, hosted-URL
fallback), move guidance to docs/guide.md, and bump both to 2.0.0
(breaking rename). The XML plugin keeps its existing CLI validator
as the non-LSP/CI/wrapper-file channel (no hook, no LSP overlap);
a flow validator and any hook are deferred.
Move the existing design specs from docs/specs/ into
docs/superpowers/specs/ (matching where the LSP-restructure spec and
plan live), and update the llms.txt link and the plan/spec
cross-references to the new paths.
Rename both marketplace plugins to lead with their LSP identity:
dataverse-customization-xml becomes dataverse-xml-lsp and
power-automate-cloud-flow becomes cloud-flow-json-lsp.

Move the plugin directories (history preserved), bump both plugin.json
to 2.0.0 with LSP-first descriptions, and update marketplace.json name,
source and descriptions. Update the flow package.json/package-lock.json
name and the flow schema $id. Update CI cache paths/keys and every doc
path, install/update command, and slug reference across the repo READMEs,
llms.txt, and per-plugin docs.

Drop the per-plugin commands/setup.md slash command; docs now point at
the setup-skill invocation.
Both plugins now launch their language server through a small node launcher
shim (scripts/lsp-launch.mjs) referenced from .lsp.json via ${CLAUDE_PLUGIN_ROOT},
which Claude Code substitutes in command/args. The shim spawns the real server
(vscode-json-language-server / the platform-specific lemminx binary), proxies LSP
stdio, and injects the bundled schema association at runtime - computing an
absolute file:// path from the passed plugin root. The association is injected in
three places (forwarded initialize, every workspace/didChangeConfiguration, and by
answering the server's workspace/configuration pull) so an empty client config
push cannot clear it.

The committed .lsp.json for both plugins is now fully portable: no machine-local
absolute path, no per-OS lemminx binary name. Install-Plugin.ps1 no longer stamps
.lsp.json; the heavy install and self-check stay. Set-LspSchemaPaths.ps1 is reduced
to its VS Code editor-association branch (a separate consumer). LspConfig tests now
assert the portable shim shape and that no machine path is present; the JSON
self-check (lsp-smoke.mjs) drives the shim itself.
Restore fail-loud guards lost when Set-LspSchemaPaths.ps1 stopped stamping:
- Each shim now checks its schema target(s) exist before launch and throws a
  clear non-zero error if missing (JSON: the .schema.json; XML: the
  schemas/<version> dir and every XSD an association points at), so a bad
  versions.json bump or partial fetch fails instead of silently validating nothing.
- The XML Install-Plugin.ps1 now verifies node is on PATH when setting up the LSP
  (the shim runs under node), matching the JSON installer; validator-only
  (-SkipLemminx) setups still skip it.
- Both shims exit on the child's close event (after stdio drains) rather than exit,
  so the last forwarded message is not truncated, and add a spawn error handler that
  reports the failing path and exits non-zero.
- SetupSkill.Tests.ps1 (both plugins): frontmatter name == <plugin>-setup,
  no description key (locks the no-auto-trigger behavior).
- Install.Tests.ps1 (both plugins): Install-Plugin runs twice and the second
  run exits 0; SKIP-guarded when node / lemminx / schemas are absent so a
  validator-only or network-less CI stays green.
- lsp-smoke.mjs + LspSmoke.Tests.ps1 (xml): drive lemminx end-to-end through
  node + the launcher shim (the validator self-check bypasses them). The client
  supplies no schema, so a firing grammar proves the shim injected the
  associations; valid ribbon -> 0 diagnostics, invalid -> >= 1.
- LspAssociations.Tests.ps1 (xml): assert the LSP is not associated to the
  pac wrapper roots the validator owns. Charts pass. The forms case FAILS:
  **/FormXml/**/*.xml -> FormXml.xsd matches pac <forms> wrapper files, so
  lemminx false-positives on the <forms> root ("cvc-elt.1.a: Cannot find the
  declaration of element 'forms'"). Left the shim unchanged and flagged the
  association per the design intent (forms should be validator-owned).
pac form files are <forms> wrappers whose root FormXml.xsd does not declare,
so lemminx false-positived on the <forms> root ("cvc-elt.1.a: Cannot find the
declaration of element 'forms'"). Removing the **/FormXml/**/*.xml association
makes them validator-owned, matching the approved design; the validator handles
them via per-fragment (systemform/form) extraction.
The 2026-07-15 repo-design and 2026-07-21 power-automate specs describe
the pre-2.0.0 plugin names and the removed /<plugin>:setup command;
keep them as dated records with a banner pointing at the current
LSP-restructure spec rather than rewriting dated docs anachronistically.
Also finalizes the plan's task tracker (all tasks completed).
@Cordedmink2
Cordedmink2 merged commit 0bc55a0 into main Jul 21, 2026
2 checks passed
@Cordedmink2
Cordedmink2 deleted the refactor/lsp-only-plugin-rename branch July 21, 2026 03:18
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.

1 participant