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.
49 lines
2.1 KiB
PowerShell
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
|
|
}
|