Module Structure and Initialization
The glean-powershell module initializes its public and private function surfaces through a coordinated interaction between a manifest file, a loader script, and a JSON-based alias registry. The manifest defines the module metadata and explicitly lists all exported functions and aliases, serving as the static contract for the module’s interface 1 2 3. The loader script dynamically discovers and dot-sources all PowerShell scripts in the Private and Public directories, ensuring that all function definitions are loaded into the session 4. Finally, the loader reads a generated aliases.json file to map standard PowerShell Verb-Noun commands to their corresponding dotted SDK-style aliases, exporting both sets to make them available to the user.
Module Manifest Configuration
Section titled “Module Manifest Configuration”The module manifest, Glean.psd1, acts as the primary configuration file that defines the module’s identity and export surface 1. It specifies Glean.psm1 as the RootModule, which is the entry point for the module’s logic. The manifest explicitly lists all public functions in the FunctionsToExport array, which includes commands such as Add-GleanCollection, Connect-Glean, and Get-GleanSearch 2. Additionally, it defines a comprehensive list of aliases in the AliasesToExport array, mapping these functions to dotted names that reflect the underlying API structure, such as Glean.client.collections.addItems and Glean.indexing.documents.index 3. The manifest also includes metadata such as the module version, GUID, and author information, along with private data tags like ‘REST’, ‘API’, and ‘OpenAPI’ 1 3.
Module Loader and Script Discovery
Section titled “Module Loader and Script Discovery”The module loader, Glean.psm1, is responsible for dynamically loading the function definitions into the PowerShell session 4. It begins by setting $ErrorActionPreference to 'Stop' to ensure that any errors during loading halt execution. The loader then uses Get-ChildItem to recursively find all .ps1 files in the Private and Public subdirectories relative to the module’s root path ($PSScriptRoot). It combines these file lists and iterates through them, dot-sourcing each file using the . $file.FullName syntax. This approach ensures that all function definitions, whether intended for internal use (Private) or external consumption (Public), are available in the module’s scope before exports are processed.
Alias Mapping and Export
Section titled “Alias Mapping and Export”After loading the scripts, the loader handles the registration of aliases to provide compatibility with SDK-style naming conventions. It looks for a file named aliases.json in the module root directory. If this file exists, the loader reads its content, converts it from JSON, and iterates through the entries. For each entry, it uses Set-Alias to map the dotted alias name (e.g., Glean.client.chat.retrieve) to the corresponding PowerShell function name (e.g., Get-GleanChat) with a script scope and force flag. Finally, the loader calls Export-ModuleMember to explicitly export the public functions (derived from the base names of the loaded public scripts) and the registered aliases. If aliases.json is missing, it falls back to exporting only the public functions.
@{
RootModule = 'Glean.psm1'
ModuleVersion = '1.0.0'
GUID = '8f2a1c4e-9b30-4d67-bf12-7a5e6c0d3e91'
Author = 'Generated from gleanwork/open-api'
CompanyName = 'Community'
Copyright = 'Generated PowerShell client for the Glean API.'
Description = 'Full PowerShell client for the published Glean Client + Indexing REST APIs. Generated from the gleanwork/open-api OpenAPI specifications (111 operations).'
PowerShellVersion = '7.2'
FunctionsToExport = @(
'Add-GleanCollection'
'Add-GleanDatasource'
'Add-GleanDocument'
'Add-GleanDocumentIndex'
'Add-GleanPermission'
'Add-GleanPermissionMembership'
'Add-GleanPermissionUser'
'Add-GleanPerson'
'Add-GleanPersonTeam'
'Add-GleanVerification'
'Connect-Glean'
'Disconnect-Glean'
'Find-GleanSearch'
'Find-GleanSearchRecommendations'
'Get-GleanAgent'
'Get-GleanAgentList'
'Get-GleanAgentSchemas'
'Get-GleanAnswer'
'Get-GleanAnswerList'
'Get-GleanChat'
'Get-GleanChatApplication'
'Get-GleanChatFile'
'Get-GleanChatFiles'
'Get-GleanChatList'
'Get-GleanCollection'
'Get-GleanCollectionList'
'Get-GleanConnection'
'Get-GleanCustomMetadata'
'Get-GleanDatasource'
'Get-GleanDocument'
'Submit-GleanActivityFeedback'
'Submit-GleanDocument'
'Submit-GleanPermission'
'Submit-GleanPerson'
'Test-GleanConnection'
'Test-GleanDocument'
'Test-GleanVerification'
'Update-GleanAuth'
'Update-GleanAuthentication'
)
CmdletsToExport = @()
VariablesToExport = @()
AliasesToExport = @(
'Glean.client.activity.feedback'
'Glean.client.activity.report'
'Glean.client.agents.createAgent'
'Glean.client.agents.editAgent'
'Glean.client.agents.list'
'Glean.client.agents.retrieve'
'Glean.client.agents.retrieveSchemas'
'Glean.client.agents.run'
'Glean.client.agents.runStream'
'Glean.client.announcements.create'
'Glean.client.announcements.delete'
'Glean.client.announcements.update'
'Glean.client.answers.create'
'Glean.client.answers.delete'
'Glean.client.answers.list'
'Glean.client.answers.retrieve'
'Glean.client.answers.update'
'Glean.client.authentication.checkdatasourceauth'
'Glean.client.authentication.createToken'
'Glean.client.chat.create'
'Glean.client.chat.delete'
'Glean.client.chat.deleteAll'
'Glean.client.chat.deleteFiles'
'Glean.client.chat.getChatFile'
'Glean.client.chat.list'
'Glean.client.chat.retrieve'
'Glean.client.chat.retrieveApplication'
'Glean.indexing.permissions.updatePermissions'
'Glean.indexing.shortcuts.bulkIndex'
'Glean.indexing.shortcuts.upload'
'Glean.indexing.troubleshooting.events'
)
PrivateData = @{
PSData = @{
Tags = @('Glean', 'REST', 'API', 'Search', 'Indexing', 'OpenAPI', 'SSO', 'MCP')
ProjectUri = 'https://github.com/gleanwork/open-api'
LicenseUri = ''
ReleaseNotes = 'Dual auth (API token + browser SSO cookie capture), pluggable providers, MCP server, integrity-gated installer.'
}
}
}
# Root module: dot-source the hand-written runtime (Private) and the generated + hand-written
# cmdlets (Public), then export the public surface and register the Speakeasy-style aliases
# recorded in contract.json so callers can use either Verb-Noun or the dotted SDK name.
$ErrorActionPreference = 'Stop'
$private = @(Get-ChildItem -Path (Join-Path $PSScriptRoot 'Private') -Filter '*.ps1' -Recurse -ErrorAction SilentlyContinue)
$public = @(Get-ChildItem -Path (Join-Path $PSScriptRoot 'Public') -Filter '*.ps1' -Recurse -ErrorAction SilentlyContinue)
foreach ($file in @($private + $public)) {
. $file.FullName
}
# Register aliases from the generated contract (function -> dotted alias).
$contractPath = Join-Path $PSScriptRoot 'aliases.json'
if (Test-Path -LiteralPath $contractPath) {
$aliases = Get-Content -LiteralPath $contractPath -Raw | ConvertFrom-Json
foreach ($entry in $aliases) {
Set-Alias -Name $entry.alias -Value $entry.function -Scope Script -Force
}
Export-ModuleMember -Function $public.BaseName -Alias ($aliases.alias)
}
else {
Export-ModuleMember -Function $public.BaseName
}