Skip to content
| Marketplace
Sign in
Visual Studio Code>Linters>SFP XML LinterNew to Visual Studio Code? Get it now.
SFP XML Linter

SFP XML Linter

Daniel Sasek

|
61 installs
| (0) | Free
IntelliSense, diagnostics, references, and template tooling for SFP XML projects.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

SFP XML Linter

VS Code extension scaffold for SFP XML linting and semantic validation.

Pre-release 0.1.25: This opt-in build adds autonomous tooling and the experimental SFP Package v2 client merge workflow. Package Apply changes client XML, the stored baseline, and its lock together; use it first in a committed or otherwise recoverable workspace and review the batch preview before confirmation. Stable Marketplace users remain on 0.1.22 unless they explicitly switch to the pre-release channel. It can also install its MCP runtime to a stable persistent path and register it for Codex and/or Claude.

Implemented foundation

  • Configurable scan roots (sfpXmlLinter.workspaceRoots), defaults:
    • XML
    • XML_Templates
    • XML_Components
  • Workspace indexer for:
    • Form symbols (Controls, Buttons, Sections)
    • Feature symbols (Contribution + contracts)
    • Primitive symbols (UsePrimitive, params, slots)
  • Diagnostics:
    • unknown-form-ident
    • unknown-form-control-ident
    • unknown-form-button-ident
    • unknown-form-section-ident
    • unknown-mapping-ident
    • unknown-mapping-form-ident
    • duplicate-control-ident
    • duplicate-button-ident
    • duplicate-section-ident
    • unknown-using-feature
    • unknown-using-contribution
    • contribution-mismatch
    • typo-maxlenght-attribute (MaxLenght typo in Control/Parameter; expected MaxLength)
    • sql-convention-equals-spacing (= in SQL/Command must have spaces on both sides)
    • primitive diagnostics:
      • unknown-primitive
      • primitive-missing-slot
      • primitive-missing-param
      • primitive-cycle
    • feature-contract diagnostics:
      • unknown-feature-requirement
      • missing-feature-dependency
      • missing-feature-expectation
      • missing-feature-expected-xpath
      • duplicate-feature-provider
      • ordering-conflict
      • orphan-feature-part
      • incomplete-feature
    • inheritance/suppression diagnostics:
      • workflow-redundant-feature-using
      • dataview-redundant-feature-using
      • feature-inheritance-override
      • suppression-conflict
      • suppression-noop
    • FormControl xsi:type="ShareCodeControl" is validated against WorkFlow/ControlShareCodes/ControlShareCode (local + injected via Using)
  • Per-rule severity config (sfpXmlLinter.rules) with values: off, information, warning, error
  • Ignore directives:
    • <!-- @Ignore rule-id --> (applies to next non-empty line)
    • <!-- @IgnoreFile rule-id --> (applies to whole file)
    • all is supported as wildcard rule id
    • SQL inline ignore is supported in SQL/Command blocks:
      • -- @Ignore rule-id
      • /* @Ignore rule-id */
    • SQL semantic highlighting ignores SQL comments (-- ..., /* ... */) to avoid placeholder/string highlighting in commented SQL.
  • Hover on diagnostics (message + rule id)
  • Color preview and picker for hex literals in XML (#RGB, #RGBA, #RRGGBB, #RRGGBBAA)
  • Completion (context-aware foundation):
    • root/child elements
    • attribute names by tag
    • enum values (xsi:type, DataType, Insert, ...)
    • semantic values (FormIdent, Using Feature/Contribution, WorkFlow Ident refs)
    • production-oriented workflow Action snippets (e.g. ChangeState, ChangeState (StateDataSource), ActionTrigger, ActionValue, GlobalValidation, Required, Communication, Email, Alert, GenerateForm, GenerateSubForm, IF)
    • ActionValue snippet defaults to DataSource (SQL + Parameters) and does not suggest inline Value for xsi:type="ActionValue"
  • Go to Definition:
    • WorkFlow@FormIdent -> <Form Ident="...">
    • any FormIdent="..." reference -> <Form Ident="...">
    • FormControl/Button/Section Ident in WorkFlow -> matching declaration in Form
    • Mapping FromIdent/ToIdent -> matching control declaration in owning Form
    • Using Feature/Name -> feature file
    • Using Contribution -> <Contribution Name="..."> in feature
    • legacy Using Component/Section is still supported (temporary compatibility)
  • Rename Symbol:
    • rename Form Ident and update all FormIdent/MappingFormIdent references
    • rename Control/Button/Section Ident from Form declaration
    • rename corresponding references in WorkFlow documents
    • for controls, rename Mapping FromIdent/ToIdent references (with MappingFormIdent support)
  • Quick fixes:
    • Ignore rule on next line (<!-- @Ignore rule-id -->)
    • Ignore rule in file (<!-- @IgnoreFile rule-id -->)
    • Ignore all rules in file (<!-- @IgnoreFile all -->)
    • SQL convention quick fixes for sql-convention-equals-spacing:
      • auto-fix spacing around =
      • add SQL inline ignore (/* @Ignore sql-convention-equals-spacing */)
  • Build command:
    • SFP XML Linter: Build XML Templates
    • SFP XML Linter: Build XML Templates (All)
    • SFP XML Linter: Normalize Template SQL/HTMLTemplate To CDATA
    • Native TypeScript BuildXmlTemplates builder (no PowerShell fallback)
    • templating naming supports both:
      • current: Feature / Contribution
      • legacy (temporary): Component / Section
    • template Using evaluation is root-level only:
      • only root <Using ... /> and root <Usings>...</Usings> are treated as template directives
      • nested Using / Usings are ignored by template composition and preserved in final XML
      • this prevents collisions with non-template XML constructs such as Razor Using / Usings
    • composition helpers:
      • UsePrimitive + XML_Primitives library
      • sugar pipeline: Repeat, If, Case
    • TargetXPath is evaluated as real XPath during section insertion
    • if multiple nodes match:
      • first match is used by default
      • AllowMultipleInserts="true" applies the insert to all matches
      • build log prints a debug line for the multi-match case
    • component save dependent rebuild behavior:
      • when a feature/component changes, dependent template selection includes related Form + sibling WorkFlow/DataView by FormIdent
      • this also applies when contribution blocks are removed/commented, so stale workflow/dataview output is cleaned up reliably
    • Placeholder sections support custom inline params:
      • {{Component:Common/Shared/Assign,Section:Html,CustomParam:ParamValue}}
      • {{Feature:Common/Shared/Assign,Contribution:Html,CustomParam:ParamValue}}
      • enables replacements inside inserted section content (e.g. {{CustomParam}})
    • output quality options:
      • sfpXmlLinter.templateBuilder.postBuildFormat (default true)
      • sfpXmlLinter.templateBuilder.provenanceMode (off | fileComment)
    • template block normalization:
      • normalizes <SQL> and <HTMLTemplate> content in XML_Templates to CDATA on demand
      • preserves already wrapped CDATA blocks
      • after normalization the file is saved and the usual rebuild chain is triggered
    • builder modes:
      • sfpXmlLinter.templateBuilder.mode (fast | debug | release)
  • build/composition output channels:
    • SFP XML Linter: Show Build Queue Log
    • SFP XML Linter: Show Composition Log
    • SFP XML Linter: Show Pipeline Stats
    • SFP XML Linter: Export Pipeline Trace
    • SFP XML Linter: Export Usage Snapshot
    • debug exports:
      • Export Pipeline Trace writes Docs/pipeline-trace.json
      • Export Usage Snapshot writes Docs/pipeline-usage-snapshot.json (model + facts + symbols + validation + pipeline)
  • Generator scaffolding commands:
    • SFP XML Linter: Create Generator Template (Document)
    • SFP XML Linter: Create Generator Template (Snippet)
    • Creates hello-world templates in XML_Generators:
      • hello.document.generator.js
      • hello.snippet.generator.js
    • If file name already exists, numeric suffix is added automatically.
    • Full generator API and examples: Docs/TemplateGenerators.MD
    • user generator settings:
      • sfpXmlLinter.templateBuilder.generators.enabled
      • sfpXmlLinter.templateBuilder.generators.timeoutMs
      • sfpXmlLinter.templateBuilder.generators.enableUserScripts
      • sfpXmlLinter.templateBuilder.generators.userScriptsRoots
  • Feature manifest bootstrap command:
    • SFP XML Linter: Generate Feature Manifest Bootstrap
    • Generates *.feature.json next to the active feature from current XML-first feature composition.
    • Uses the same auto-manifest inference as runtime (Feature/Contribution, contracts, expectsXPath, requires, provides).
    • If target file already exists, asks for explicit overwrite confirmation.
    • Full usage guide: Docs/FeatureManifestBootstrap.md
    • Authoring guide (contracts + diagnostics): Docs/FeatureManifestAuthoring.md
  • Report command:
    • SFP XML Linter: Workspace Diagnostics Report
    • Prints diagnostics summary and per-rule counts to output channel
  • Composition view commands:
    • SFP XML Linter: Refresh Composition View
    • SFP XML Linter: Composition Open Source
    • Tree View shows:
      • local/injected symbols
      • Using status (effective / partial / unused / inert)
      • contribution meta and insert trace (TargetXPath, matches, inserts, placeholder usage)
  • Index command:
    • SFP XML Linter: Rebuild Full Index
    • Forces full workspace reindex on demand
  • Revalidate command:
    • SFP XML Linter: Revalidate Workspace (Full)
    • Runs full reindex and then revalidates all XML files in configured roots
  • Tolerant formatter commands:
    • SFP XML Linter: Format Document (Tolerant)
    • SFP XML Linter: Format Selection (Tolerant)
    • Extension is registered as XML format provider (and default formatter via extension configuration defaults).
    • Handles invalid XML nesting with recovery/fallback behavior.
    • Supports @FormatRule directives:
      • <!-- @FormatRule:disable -->
      • <!-- @FormatRule:preserve-inner -->
      • <!-- @FormatRule:format-inner -->
      • <!-- @FormatRule:no-type-first -->
      • <!-- @FormatRule:no-attr-normalize -->
      • <!-- @FormatRule:no-inline-text-normalize -->
      • Multiple rules in one directive are supported (comma/space separated).
    • Preserves inner content for SQL, SQLCommand, HTMLTemplate, and XMLDescription (reindents leading whitespace only by default).
    • Command is auto-suppressed (no formatting is applied by default unless @FormatRule:format-inner is used).
    • Consecutive blank lines are preserved but clamped by sfpXmlLinter.formatter.maxConsecutiveBlankLines (default 2).

Startup behavior

  • On startup, diagnostics are evaluated only for user-open documents (visible editors / open tabs).
  • Files opened internally by indexer are ignored for diagnostics.
  • Full workspace indexing runs in background (non-blocking startup).

Incomplete Mode and External Tables

  • VS Code setting: sfpXmlLinter.incompleteMode (false by default)
    • when enabled, suppresses diagnostics that require unknown FormIdent resolution (e.g. unknown-form-ident, unknown-mapping-form-ident, and dependent unknown-mapping-ident cases).
  • External tables can be declared in workspace root file:
    • .sfpxmlsetting (preferred)
    • .sfpxmlsettings (also supported)

Minimal example:

{
  "externalTables": {
    "ExternalTicket": ["ID", "Ident", "Code"],
    "dbo.LegacyOrder": {
      "columns": ["ID", "OrderNumber"]
    }
  }
}

Notes:

  • Both TableName and dbo.TableName are accepted for FormIdent.
  • External table columns are used by lookup-ident convention checks (DropDown/AutoComplete/ListBox/DualListBox).

Index domains

  • Indexing is isolated into 2 independent domains:
    • template domain: XML_Templates + XML_Components
    • runtime domain: XML
  • Diagnostics, completion, definition, references, and rename use the domain of the current document.
  • This prevents symbol collisions when the same Form Ident exists in both template and runtime trees.
  • Reindex/rebuild operations update both domains, but symbol resolution never mixes them.
  • Template Using parsing follows one shared root-level model across:
    • render/build
    • inherited using propagation
    • dependency discovery

Product development

  • Backlog nezpracovaných nápadů
  • Přehled rozpracovaných návrhů
  • Přehled implementačních plánů

Práce postupuje řízeně přes Backlog -> Návrh -> Implementační plán -> Implementace.

Package v2 client merge

Panel SFP Package Updates poskytuje batch workflow Base/Local/Incoming pro promítnutí nové verze balíčku do klientsky upravených XML. Stejné merge operace jsou dostupné přes CLI, MCP a VS Code AI tools. Repo kontrakt, strategie, bezpečnostní brány a postup jsou v Klientský merge SFP Package v2.

Merge je v 0.1.23 publikován jako experimentální pre-release. Analyze a review pracují v ignorované .sfp/package-overlays/.work/; zápis klientských XML, baseline a locku proběhne až přes Validate → Preview → potvrzený Apply.

AI and automation tooling

The tooling runtime exposes all 33 catalogued capabilities, including workspace inspection/configuration, validation, template build, composition queries, deterministic fixes, transforms and generation through the VS Code Language Model Tool API, a JSON CLI, and a local STDIO MCP server. The existing VS Code selected/full build, compare, and pipeline report commands use the same capability layer. The extension also provides AI commands for diagnostic explanation, summary and structured fix suggestion. Live pipeline telemetry is available in the VS Code process; standalone CLI/MCP callers receive an explicit unavailable result. See AI and automation tooling for the implemented capability list and AI client setup for persistent Codex/Claude registration. Every MCP call selects its repository explicitly through an absolute workspaceRoot; runtime state is isolated between repositories.

Dev

npm install
npm run compile
npm run test:linter
npm run test:formatter
npm run test:tooling
npm run test:e2e:basic
npm run test:templates
npm run test:templates:perf
npm run tooling:schemas:generate
npm run package:vsix:pre-release

Run extension in VS Code with F5 (Extension Development Host).

Hover docs files

Hover documentation is loaded from configurable JSON files:

  • Setting: sfpXmlLinter.hoverDocsFiles
  • Default:
    • Docs/hover-docs.json
    • Docs/hover-docs.team.json
  • Changes in these files are reloaded automatically (no extension host restart required).
  • If multiple entries match with the same relevance, later files in hoverDocsFiles win (override behavior).
  • If no external hover docs file is available, built-in fallback docs (derived from SFPDocs) are used automatically.

Minimal file format:

{
  "entries": [
    {
      "tag": "Form",
      "summary": "Short description",
      "details": "Optional concise detail."
    },
    {
      "attribute": "FormIdent",
      "summary": "Reference to Form Ident"
    }
  ]
}

Example override in VS Code settings:

{
  "sfpXmlLinter.hoverDocsFiles": [
    "Docs/hover-docs.json",
    "Docs/hover-docs.team.json",
    "Docs/hover-docs.custom.json"
  ]
}
  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft