Skip to main content

Internal Plugin System

warning

Version 1 plugins are an internal trusted-code mechanism, not a stable public SDK. They execute without a sandbox and can access the same files, processes, network, and credentials as the generator process.

Directory Layout

A plugin root may contain:

Plugins/
├── Inspectors/
├── Validators/
├── ObjectModelProcessors/
├── RuntimeAdapters/
├── CodeGenerators/
├── TemplateRenderers/
└── PackagingProviders/

Files must match:

<numeric-prefix>.<name>.ps1

Example:

Inspectors/20.DirectoryPolicyInspector.ps1

Discovery and Ordering

Stages always execute in pipeline order. Within a stage, files are sorted by ordinal filename and then resolved path. Numeric prefixes communicate intent, but the full filename determines lexical order; use zero-padded prefixes consistently.

Inspect without executing:

Get-PSModulePlugin `
-Path ./PSModule/Plugins

Filter stages:

Get-PSModulePlugin `
-Path ./PSModule/Plugins `
-Stage Inspectors, Validators

Duplicate roots, missing roots, and invalid filenames are rejected.

Plugin Contract

Every plugin is a PowerShell script declaring a Context parameter:

param (
[Parameter(Mandatory)]
[psobject] $Context
)

An inspector example:

param (
[Parameter(Mandatory)]
[psobject] $Context
)

$policyPath = Join-Path $Context.DirectoryPath 'directory-policy.json'
$Context.Inspection['DirectoryPolicy'] = if (
Test-Path -LiteralPath $policyPath -PathType Leaf
) {
Get-Content -LiteralPath $policyPath -Raw | ConvertFrom-Json
}
else {
$null
}

Do not write ordinary pipeline output; the runner discards it. Communicate through the shared context.

Local Plugins

When PluginPath is omitted, build and inspection commands discover Plugins beside the resolved specification:

PSModule/
├── PSModule.psd1
└── Plugins/
└── Inspectors/
└── 20.DirectoryPolicyInspector.ps1

Select explicit additional roots:

Build-PSModule `
-Specification ./PSModule/PSModule.psd1 `
-PluginPath ./Build/PSModulePlugins

Built-in plugins always run. Explicit roots do not replace them.

Diagnostics

Every attempted plugin records:

  • stage;
  • execution order;
  • plugin name and path;
  • UTC start time;
  • elapsed duration;
  • success; and
  • error text.
$inspection = Get-PSModuleInspection
$inspection | Get-PSModuleDiagnostic
$inspection | Get-PSModuleDiagnostic -Detailed

The runner wraps ordinary failures with plugin and stage identity. Failures stop the stage and the remaining pipeline.

Authoring Rules

  • Treat the context shape as internal and version-coupled.
  • Validate required context properties before changing them.
  • Use directory-relative paths and normalize separators in persisted metadata.
  • Sort discovered files and object properties ordinally.
  • Do not embed development-machine absolute paths in generated artifacts.
  • Produce focused errors that name the source artifact.
  • Avoid network access unless the directory contract explicitly requires it.
  • Never log tokens, credentials, secret contents, or unredacted environment state.
  • Add fixture-backed tests for plugin behavior.