param(
[string]$RepoPath = (Get-Location).Path,
[string]$DbPassword,
[ValidateSet("Sample", "Empty", "Path")]
[string]$ContentMode = "Sample",
[string]$ContentPath,
[switch]$Reset,
[switch]$WriteEnabled,
[string]$McpAuthUsername,
[string]$McpAuthPassword,
[switch]$AuthFromDb,
[switch]$OpenUi,
[switch]$SkipBuild
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
function Require-Command {
param([string]$Name)
if (-not (Get-Command $Name -ErrorAction SilentlyContinue)) {
throw "Missing required command: $Name"
}
}
function Set-EnvValue {
param(
[string]$Content,
[string]$Key,
[string]$Value
)
$pattern = "(?m)^\s*$Key\s*=.*$"
if ($Content -match $pattern) {
return [regex]::Replace($Content, $pattern, "$Key=$Value")
}
$suffix = if ($Content.EndsWith("`n")) { "" } else { "`r`n" }
return "$Content$suffix$Key=$Value`r`n"
}
function Get-EnvValue {
param(
[string]$Content,
[string]$Key
)
$pattern = "(?m)^\s*$Key\s*=\s*(.*)$"
if ($Content -match $pattern) {
return $Matches[1].Trim()
}
return $null
}
Require-Command "git"
Require-Command "docker"
$repoRoot = Resolve-Path $RepoPath
$composeFile = Join-Path $repoRoot "docker-compose.yml"
if (-not (Test-Path $composeFile)) {
throw "docker-compose.yml not found. Run from the repo root or pass -RepoPath."
}
$envExample = Join-Path $repoRoot ".env.example"
$envFile = Join-Path $repoRoot ".env"
if (-not (Test-Path $envExample)) {
throw ".env.example not found."
}
$createdEnv = $false
if (-not (Test-Path $envFile)) {
Copy-Item $envExample $envFile
$createdEnv = $true
}
$envContent = Get-Content $envFile -Raw
if ($DbPassword) {
$envContent = Set-EnvValue -Content $envContent -Key "WIKI_DB_PASSWORD" -Value $DbPassword
} elseif ($createdEnv) {
$generated = [guid]::NewGuid().ToString("n")
$envContent = Set-EnvValue -Content $envContent -Key "WIKI_DB_PASSWORD" -Value $generated
}
if ($WriteEnabled.IsPresent) {
$envContent = Set-EnvValue -Content $envContent -Key "WIKI_WRITE_ENABLED" -Value "true"
}
switch ($ContentMode) {
"Sample" {
$contentDir = "./wiki-content"
}
"Empty" {
$contentDir = "./wiki-content-empty"
}
"Path" {
if (-not $ContentPath) {
throw "ContentMode 'Path' requires -ContentPath."
}
$contentDir = $ContentPath
}
}
$contentDirResolved = if ([System.IO.Path]::IsPathRooted($contentDir)) {
$contentDir
} else {
Join-Path $repoRoot $contentDir
}
if (-not (Test-Path $contentDirResolved)) {
New-Item -ItemType Directory -Force -Path $contentDirResolved | Out-Null
}
if ($ContentMode -eq "Empty") {
$localeDir = Join-Path $contentDirResolved "en"
if (-not (Test-Path $localeDir)) {
New-Item -ItemType Directory -Force -Path $localeDir | Out-Null
}
}
$envContent = Set-EnvValue -Content $envContent -Key "WIKI_CONTENT_DIR" -Value $contentDir
if ($AuthFromDb.IsPresent) {
$dbUser = Get-EnvValue -Content $envContent -Key "WIKI_DB_USER"
if (-not $dbUser) {
$dbUser = "wikijs"
}
$dbPassword = Get-EnvValue -Content $envContent -Key "WIKI_DB_PASSWORD"
if (-not $dbPassword) {
throw "WIKI_DB_PASSWORD is required to mirror DB creds for MCP auth."
}
$envContent = Set-EnvValue -Content $envContent -Key "MCP_AUTH_USERNAME" -Value $dbUser
$envContent = Set-EnvValue -Content $envContent -Key "MCP_AUTH_PASSWORD" -Value $dbPassword
} elseif ($McpAuthUsername -or $McpAuthPassword) {
if (-not $McpAuthUsername -or -not $McpAuthPassword) {
throw "Both -McpAuthUsername and -McpAuthPassword are required."
}
$envContent = Set-EnvValue -Content $envContent -Key "MCP_AUTH_USERNAME" -Value $McpAuthUsername
$envContent = Set-EnvValue -Content $envContent -Key "MCP_AUTH_PASSWORD" -Value $McpAuthPassword
}
Set-Content -Path $envFile -Value $envContent
$compose = "docker compose"
try {
& docker compose version *> $null
} catch {
$compose = "docker-compose"
}
Push-Location $repoRoot
if ($Reset) {
& $compose down -v
}
if ($SkipBuild) {
& $compose up -d
} else {
& $compose up -d --build
}
Pop-Location
Write-Host "Wiki UI: http://localhost:3030"
Write-Host "Git storage path: file:///wiki-storage"
Write-Host "Content dir: $contentDir"
if ($OpenUi.IsPresent) {
Start-Process "http://localhost:3030"
}