Files
claude-mode/bin/claude-key-helper.ps1
T
smoido 112068314c Import claude-code-switcher from the Windows build
Source of truth so far has been c:\Users\smoido\projects\cli on the Windows
box, which has no git history of its own. This is that tree copied verbatim over
SSH, minus dist/ - the PowerShell build, the POSIX port under linux/, and the
presets both share.

Recorded as its own commit so that everything after it is a reviewable diff
rather than an undifferentiated first drop.
2026-08-30 21:05:48 +03:00

49 lines
2.1 KiB
PowerShell

# claude-key-helper.ps1
#
# Invoked by Claude Code via the `apiKeyHelper` setting. Prints the API key for
# the currently active preset to stdout and nothing else.
#
# Only presets whose auth mode is "vault" have a secret to emit. In anthropic
# mode, or for a preset using an inline placeholder token (LM Studio), this
# exits silently so no token can leak into a context that must not have one.
#
# The key is stored DPAPI-encrypted (CurrentUser scope), so decryption only
# succeeds for the Windows account that ran `claude-mode set-key`. Reading the
# .cred file as another user - or copying it to another machine - yields nothing.
$ErrorActionPreference = 'Stop'
try {
$root = Join-Path $env:USERPROFILE '.claude-mode'
$state = Get-Content -LiteralPath (Join-Path $root 'state.json') -Raw -Encoding UTF8 | ConvertFrom-Json
if ($state.mode -eq 'anthropic') { exit 0 }
if (-not $state.preset) { exit 0 }
$presetPath = Join-Path $root ('presets\' + $state.preset + '.json')
if (-not (Test-Path -LiteralPath $presetPath)) { exit 1 }
$preset = Get-Content -LiteralPath $presetPath -Raw -Encoding UTF8 | ConvertFrom-Json
$authMode = 'vault'
$keyRef = 'openrouter'
if ($preset.PSObject.Properties.Name -contains 'auth' -and $preset.auth) {
if ($preset.auth.PSObject.Properties.Name -contains 'mode' -and $preset.auth.mode) { $authMode = [string]$preset.auth.mode }
if ($preset.auth.PSObject.Properties.Name -contains 'keyRef' -and $preset.auth.keyRef) { $keyRef = [string]$preset.auth.keyRef }
}
if ($authMode -ne 'vault') { exit 0 } # inline token: nothing for us to emit
$credPath = Join-Path $root ('vault\' + $keyRef + '.cred')
if (-not (Test-Path -LiteralPath $credPath)) { exit 1 }
$secure = ConvertTo-SecureString (Get-Content -LiteralPath $credPath -Raw).Trim()
$bstr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($secure)
try {
[Console]::Out.Write([Runtime.InteropServices.Marshal]::PtrToStringBSTR($bstr))
} finally {
[Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr)
}
} catch {
exit 1
}