Files
smoidoandClaude Opus 5 4091746d4e Split the Windows script into modules; drop the Arkylx Index pieces
claude-mode.ps1 was 2,407 lines. It is now 153: the help block, parameters,
paths, the managed-key list, a loader, and the dispatch. The rest moved,
verbatim, into eleven files under lib/ - providers, output, files, core,
vault, switch, guards, health, catalogue, commands, menu - dot-sourced into
the script's scope in their original order, with the same check as the bash
split that every original line landed in exactly one file. Inside a module
$PSScriptRoot is lib\, so the one path beside the main script
(providers.json) now goes through $script:Here.

install.ps1 ships lib\, clearing old modules first. The Windows suite
parses every module and install.ps1 (36 checks, all green on Windows
PowerShell 5.1); install.ps1 is parsed but never run, since it edits the
real profile and User PATH.

linux/bootstrap.sh and scripts/build-package.ps1 existed only to build and
serve packages for the Arkylx Index. Both installers fetch the repository's
own archive, so a push to master is the release; the two scripts, the dist/
ignore and their mentions in the docs are gone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-15 02:06:45 +03:00

87 lines
3.3 KiB
PowerShell

# lib/core.ps1 - state.json, presets, and which preset a mode resolves to.
#
# Part of claude-mode.ps1, which dot-sources it into its own script scope after
# the settings at its top. Not meant to run on its own. ASCII only: Windows
# PowerShell 5.1 reads a .ps1 without a BOM as ANSI. $PSScriptRoot here would be
# lib\, so paths beside the main script go through $script:Here.
# ---------------------------------------------------------------------------
# State / presets
# ---------------------------------------------------------------------------
function Initialize-Root {
foreach ($d in @($script:Root, $script:PresetDir, $script:VaultDir, $script:BackupDir, $script:BinDir)) {
if (-not (Test-Path -LiteralPath $d)) { New-Item -ItemType Directory -Path $d -Force | Out-Null }
}
}
function Get-State {
$s = Read-JsonFile $script:StatePath
if ($null -eq $s) { $s = [ordered]@{} }
if (-not $s.Contains('mode')) { $s['mode'] = 'anthropic' }
if (-not $s.Contains('preset')) { $s['preset'] = '' }
if (-not $s.Contains('writtenEnvKeys')) { $s['writtenEnvKeys'] = @() }
return $s
}
function Set-State {
param([string] $Mode, [string] $PresetName, [string[]] $WrittenKeys)
$s = Get-State
$s['mode'] = $Mode
$s['preset'] = $PresetName
$s['writtenEnvKeys'] = @($WrittenKeys)
$s['updated'] = (Get-Date).ToString('o')
# Written by older builds that picked "most recently used" presets; the
# per-provider default is fixed now, so nothing maintains this.
if ($s.Contains('lastByProvider')) { $s.Remove('lastByProvider') }
Write-JsonFile $script:StatePath $s
}
function Get-PresetPath { param([string] $Name) return (Join-Path $script:PresetDir "$Name.json") }
function Get-Preset {
param([string] $Name)
$p = Read-JsonFile (Get-PresetPath $Name)
if ($null -eq $p) { throw "preset '$Name' not found. Run: claude-mode presets" }
if (-not $p.Contains('provider')) { $p['provider'] = 'openrouter' }
return $p
}
function Get-PresetNames {
if (-not (Test-Path -LiteralPath $script:PresetDir)) { return @() }
return @(Get-ChildItem -LiteralPath $script:PresetDir -Filter '*.json' |
ForEach-Object { $_.BaseName } | Sort-Object)
}
function Get-PresetNamesForProvider {
param([string] $Provider)
$out = @()
foreach ($n in Get-PresetNames) {
try { if ([string](Get-Preset $n)['provider'] -eq $Provider) { $out += $n } } catch { }
}
return $out
}
function Resolve-PresetForProvider {
param([string] $Provider, [string] $Requested)
if ($Requested) {
$p = Get-Preset $Requested
if ([string]$p['provider'] -ne $Provider) {
throw "preset '$Requested' is a '$($p['provider'])' preset, not '$Provider'"
}
return $Requested
}
# Fixed per-provider default, so `claude-mode openrouter` is predictable
# rather than depending on what you last used or on alphabetical order.
$fallback = $script:ProviderDefaultPreset[$Provider]
if ($fallback -and (Test-Path -LiteralPath (Get-PresetPath $fallback))) {
if ([string](Get-Preset $fallback)['provider'] -eq $Provider) { return $fallback }
}
$names = Get-PresetNamesForProvider $Provider
if ($names.Count -gt 0) { return $names[0] }
throw "no preset found for provider '$Provider'"
}