workspace.psm1
|
# Workspace module for Delta-Code # Manages workspace registry, active context, and context switching # Resolve module dependencies from the sibling directory when available (repository # and flat-install layouts) and fall back to module-name resolution (PSGallery). foreach ($dependencyName in @('delta-code', 'satellite')) { $dependencyManifest = Join-Path $PSScriptRoot "$dependencyName.psd1" if (Test-Path -LiteralPath $dependencyManifest) { Import-Module $dependencyManifest -ErrorAction Stop -DisableNameChecking } else { Import-Module $dependencyName -ErrorAction Stop -DisableNameChecking } } Remove-Variable dependencyName, dependencyManifest -ErrorAction SilentlyContinue $script:WorkspaceRegistryPath = Get-DeltaCodeDataPath -FileName 'workspaces.json' $script:WorkspaceRegistry = @{} $script:ActiveWorkspace = $null function Save-WorkspaceRegistry { $data = @{ Workspaces = $script:WorkspaceRegistry.Values ActiveWorkspace = if ($script:ActiveWorkspace) { $script:ActiveWorkspace.Name } else { $null } } $data | ConvertTo-Json -Depth 5 | Set-Content -Path $script:WorkspaceRegistryPath -Encoding UTF8 } function Load-WorkspaceRegistry { if (Test-Path $script:WorkspaceRegistryPath) { $data = Get-Content $script:WorkspaceRegistryPath -Raw | ConvertFrom-Json if ($data.Workspaces) { $script:WorkspaceRegistry = @{} foreach ($ws in $data.Workspaces) { $script:WorkspaceRegistry[$ws.Name] = $ws } } if ($data.ActiveWorkspace) { $script:ActiveWorkspace = $script:WorkspaceRegistry[$data.ActiveWorkspace] } } } # Load registry on module import Load-WorkspaceRegistry function Get-DeltaCodeWorkspace { [CmdletBinding()] param( [Parameter(Mandatory = $true, Position = 0)] [string]$Name ) Load-WorkspaceRegistry if ($script:WorkspaceRegistry.ContainsKey($Name)) { return $script:WorkspaceRegistry[$Name] } Write-Error "Workspace '$Name' not found in registry" return $null } function Get-DeltaCodeWorkspaces { [CmdletBinding()] param( [string[]]$Filter ) Load-WorkspaceRegistry $ws = $script:WorkspaceRegistry.Values if ($Filter) { $ws = $ws | Where-Object { $Filter -contains $_.Category } } return $ws } function Register-DeltaCodeWorkspace { [CmdletBinding()] param( [Parameter(Mandatory = $true, Position = 0)] [string]$Name, [Parameter(Mandatory = $true, Position = 1)] [string]$Root, [Parameter(Mandatory = $false)] [string]$Category = 'General', [Parameter(Mandatory = $false)] [string]$Satellite = $null, [Parameter(Mandatory = $false)] [string]$Description = '', [Parameter(Mandatory = $false)] [hashtable]$Metadata = @{} ) Load-WorkspaceRegistry $normalizedRoot = (Resolve-Path -LiteralPath $Root).ProviderPath if (-not (Test-Path $normalizedRoot)) { Write-Error "Workspace root path does not exist: $normalizedRoot" return $false } $workspace = [PSCustomObject]@{ Name = $Name Root = $normalizedRoot Category = $Category Satellite = $Satellite Description = $Description Metadata = $Metadata Registered = (Get-Date -Format 'yyyy-MM-dd HH:mm:ss') Active = $false } $script:WorkspaceRegistry[$Name] = $workspace Save-WorkspaceRegistry Write-Verbose "Registered workspace '$Name' at $normalizedRoot" return $true } function Set-DeltaCodeWorkspace { [CmdletBinding()] param( [Parameter(Mandatory = $true, Position = 0)] [string]$Name ) Load-WorkspaceRegistry $ws = Get-DeltaCodeWorkspace -Name $Name if (-not $ws) { return $false } if ($script:ActiveWorkspace) { $script:ActiveWorkspace.Active = $false } $ws.Active = $true $script:ActiveWorkspace = $ws Save-WorkspaceRegistry Write-Verbose "Active workspace set to '$Name' ($($ws.Root))" return $true } function Test-DeltaCodeWorkspace { [CmdletBinding()] param( [Parameter(Mandatory = $true, Position = 0)] [string]$Name ) Load-WorkspaceRegistry $ws = Get-DeltaCodeWorkspace -Name $Name if (-not $ws) { return $false } $valid = $true $issues = @() if (-not (Test-Path $ws.Root)) { $issues += "Workspace root does not exist: $($ws.Root)" $valid = $false } if ($ws.Satellite) { $sat = Get-DeltaCodeSatellite -Name $ws.Satellite if (-not $sat) { $issues += "Referenced satellite not found: $($ws.Satellite)" $valid = $false } } if (-not $valid) { Write-Warning "Workspace '$Name' validation failed: $($issues -join '; ')" } else { Write-Verbose "Workspace '$Name' validated successfully" } return $valid } function Initialize-DeltaCodeWorkspaces { [CmdletBinding()] param( [string[]]$SearchPaths ) Load-WorkspaceRegistry if (-not $SearchPaths) { $SearchPaths = @( "$PSScriptRoot\workspaces", "$PSScriptRoot\..\workspaces", (Join-Path $env:USERPROFILE ".delta-code\workspaces") ) } foreach ($basePath in $SearchPaths) { if (Test-Path $basePath) { $dirs = Get-ChildItem -Path $basePath -Directory foreach ($dir in $dirs) { $wsName = $dir.Name $wsPath = $dir.FullName $manifest = Join-Path $wsPath "$wsName.json" if (Test-Path $manifest) { $config = Get-Content $manifest -Raw | ConvertFrom-Json Register-DeltaCodeWorkspace -Name $wsName -Path $wsPath -Category $config.Category -Satellite $config.Satellite -Description $config.Description -Metadata $config.Metadata } } } } # Auto-validate all registered $names = @($script:WorkspaceRegistry.Keys) foreach ($name in $names) { Test-DeltaCodeWorkspace -Name $name } } function Unregister-DeltaCodeWorkspace { [CmdletBinding()] param( [Parameter(Mandatory = $true, Position = 0)] [string]$Name ) Load-WorkspaceRegistry if ($script:WorkspaceRegistry.ContainsKey($Name)) { if ($script:ActiveWorkspace -and $script:ActiveWorkspace.Name -eq $Name) { $script:ActiveWorkspace = $null } $script:WorkspaceRegistry.Remove($Name) Save-WorkspaceRegistry Write-Verbose "Unregistered workspace '$Name'" return $true } return $false } function Get-DeltaCodeActiveWorkspace { [CmdletBinding()] param() Load-WorkspaceRegistry return $script:ActiveWorkspace } Export-ModuleMember -Function @( 'Get-DeltaCodeWorkspace' 'Get-DeltaCodeWorkspaces' 'Register-DeltaCodeWorkspace' 'Set-DeltaCodeWorkspace' 'Test-DeltaCodeWorkspace' 'Initialize-DeltaCodeWorkspaces' 'Unregister-DeltaCodeWorkspace' 'Get-DeltaCodeActiveWorkspace' ) |