Kritical.PS.OpenApi.psm1

<#
.SYNOPSIS
    Krit.OpenApi — Kritical OpenAPI toolkit. Canonical OpenAPI 3.x -> PowerShell
    module generator + spec validator + coverage differ + agentic sidecar
    emitter.

.DESCRIPTION
    Single module that owns every Kritical-side OpenAPI workflow:

      - Invoke-KritOpenApiGenerate : spec.json -> Krit.<Brand>OpenApi.psm1 with
        full IntelliSense (parameter types from schema, ValidateSet enums,
        pipeline binding on id-shaped path params, SupportsShouldProcess on
        DELETE / non-idempotent POST, retry/timeout/paging in the shared
        Invoke-<Brand>Api helper).
      - Test-KritOpenApiSpec : structural validation of OpenAPI 3.0/3.1
        documents (paths, components, operationIds, schemas).
      - Get-KritOpenApiCoverage : diff spec endpoints vs the generated PS
        function inventory; FAIL when a generated module drifts from its spec.
      - New-KritOpenApiAgenticSidecar : emits a Test-Xxx connectivity prover +
        Resolve-XxxAgentTask procedure per WAVE-5079 design so an off-to-the-
        side claude/codex/cowork agent can connect + prove + report end-to-end
        without main-session orchestration.
      - Write/Get-KritOpenApiBanner : Kritical brand banner. 3-tier fallback —
        canonical OneDrive Kritical-Branding path > Secrets folder > bundled
        Assets/kritical-logo.txt. Per HARD RULE 13 (CLAUDE.md).

    Soft-imports Krit.OmniFramework foundation via the .1.0.2 resilience pattern
    (ExternalModuleDependencies in psd1, NOT RequiredModules) so a stale
    PSFramework AppDomain lock cannot cascade through and block Import-Module.

    Joshua Finley · Kritical Pty Ltd · https://kritical.net
#>


Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

# ─── Soft-load Krit.OmniFramework (no hard fail when missing/locked) ───────
$script:KritOpenApiFoundationLoaded = $false
try {
    if (Get-Module -ListAvailable -Name Krit.OmniFramework -ErrorAction SilentlyContinue) {
        Import-Module Krit.OmniFramework -ErrorAction Stop
        if (Get-Command -Name Import-KritFoundation -ErrorAction SilentlyContinue) {
            Import-KritFoundation -ErrorAction SilentlyContinue | Out-Null
        }
        $script:KritOpenApiFoundationLoaded = $true
    }
} catch {
    Write-Verbose "[Krit.OpenApi] OmniFramework soft-load skipped: $($_.Exception.Message)"
}

# ─── Dot-source Private then Public ─────────────────────────────────────────
$here = Split-Path -Parent $PSCommandPath
foreach ($dir in 'Private','Public') {
    $folder = Join-Path $here $dir
    if (Test-Path -LiteralPath $folder) {
        Get-ChildItem -LiteralPath $folder -Filter '*.ps1' -File | Sort-Object Name | ForEach-Object {
            . $_.FullName
        }
    }
}

Export-ModuleMember -Function @(
    'Invoke-KritOpenApiGenerate'
    'Test-KritOpenApiSpec'
    'Get-KritOpenApiCoverage'
    'New-KritOpenApiAgenticSidecar'
    'Write-KritOpenApiBanner'
    'Get-KritOpenApiBanner'
)