diff --git a/README.md b/README.md index 65855e6..f3c41ee 100644 --- a/README.md +++ b/README.md @@ -106,13 +106,18 @@ Linux/Bash-интерфейс `proxy-client` поддерживает внешн [Установка, выбор режима, WSL и ежедневное использование](proxy-client/README.md) описаны рядом с пакетом. Windows PowerShell и ярлык `Codex Proxy` сохраняют прежнюю интеграцию с `hproxy.local:12334`. Ярлык запускает упакованное -приложение через системный идентификатор и передаёт ему параметры Chromium -`--proxy-server` и `--proxy-bypass-list`. +приложение через системный идентификатор и передаёт параметры Chromium +`--proxy-server` и `--proxy-bypass-list`. Сам Codex и его дочерние процессы +читают общие proxy-переменные из `~/.codex/.env`; пользовательское окружение +Windows не меняется. Если Codex уже запущен, его нужно полностью закрыть перед +запуском через `Codex Proxy`. `Claude Proxy` поддерживает как обычную установку в `%LOCALAPPDATA%\AnthropicClaude`, так и пакет из Microsoft Store. В обоих случаях он передаёт параметры Electron `--proxy-server` и `--proxy-bypass-list`, чтобы прокси применялся ко всему трафику Claude Desktop. +Ярлык использует скрытый промежуточный запускатель, поэтому Claude не открывает +и не удерживает окно Windows Terminal. Если Claude уже запущен обычным способом, его нужно полностью закрыть перед запуском через `Claude Proxy`. @@ -179,10 +184,12 @@ Linux/Bash-интерфейс `proxy-client` поддерживает внешн | Файл | Назначение | |------|------------| | `~/.env.secrets` | API-ключи, подгружается bash и VS Code Server | +| `~/.codex/.env` | Общие proxy-переменные для Codex CLI, Codex Desktop и их дочерних процессов | | `~/.bash_aliases` | Персональные алиасы bash | | `~/.gitconfig.local` | Персональные Git-настройки (`user.name`, `core.editor` и т.д.) | | `~/.local/bin/start-claude-proxy.ps1` | Скрипт запуска Claude Desktop для Windows с переменными прокси и параметрами Electron | -| `~/.local/bin/start-codex-proxy.ps1` | Запуск Codex для Windows через системный идентификатор с параметрами прокси | +| `~/.local/bin/start-claude-proxy.vbs` | Скрытый запуск PowerShell-скрипта без привязки Claude к видимому окну терминала | +| `~/.local/bin/start-codex-proxy.ps1` | Запуск Codex для Windows через системный идентификатор; прокси Electron задаётся параметрами, а `codex.exe` читает `~/.codex/.env` | | `~/.config/powershell/profile.extra.ps1` | Локальные дополнения к pwsh-профилю | | `~/.config/powershell/profile.d/*.ps1` | Фрагменты, загружаемые по алфавиту | | `~/.claude/settings.json` | Управляется Claude Code: `model`, `effortLevel`, «always allow» permissions | diff --git a/chezmoi/.chezmoiscripts/run_31-create-claude-proxy-shortcut.ps1 b/chezmoi/.chezmoiscripts/run_31-create-claude-proxy-shortcut.ps1 index 6ad74a7..84833f4 100644 --- a/chezmoi/.chezmoiscripts/run_31-create-claude-proxy-shortcut.ps1 +++ b/chezmoi/.chezmoiscripts/run_31-create-claude-proxy-shortcut.ps1 @@ -5,6 +5,7 @@ if (-not ($IsWindows -or $PSVersionTable.PSEdition -eq 'Desktop')) { } $LauncherPath = Join-Path $HOME '.local\bin\start-claude-proxy.ps1' +$LauncherHostPath = Join-Path $HOME '.local\bin\start-claude-proxy.vbs' $ProgramsPath = [Environment]::GetFolderPath('Programs') if ([string]::IsNullOrWhiteSpace($ProgramsPath)) { Write-Warning 'Start Menu Programs folder was not found.' @@ -12,17 +13,8 @@ if ([string]::IsNullOrWhiteSpace($ProgramsPath)) { } $ShortcutPath = Join-Path $ProgramsPath 'Claude Proxy.lnk' -$PwshAliasPath = Join-Path $env:LOCALAPPDATA 'Microsoft\WindowsApps\pwsh.exe' -$PwshCommand = Get-Command pwsh -ErrorAction SilentlyContinue -if (Test-Path -LiteralPath $PwshAliasPath) { - $TargetPath = $PwshAliasPath -} elseif ($null -ne $PwshCommand) { - $TargetPath = $PwshCommand.Source -} else { - $TargetPath = 'pwsh.exe' -} - -$Arguments = "-NoLogo -NoProfile -ExecutionPolicy Bypass -File `"$LauncherPath`"" +$TargetPath = Join-Path $env:WINDIR 'System32\wscript.exe' +$Arguments = "//NoLogo `"$LauncherHostPath`"" $WorkingDirectory = $env:USERPROFILE function Get-ClaudeIconExecutable { @@ -60,7 +52,7 @@ $ClaudeExecutable = Get-ClaudeIconExecutable if ($null -ne $ClaudeExecutable) { $IconLocation = "$ClaudeExecutable,0" } else { - $IconLocation = "$TargetPath,0" + $IconLocation = "$LauncherPath,0" } New-Item -ItemType Directory -Path (Split-Path -Parent $ShortcutPath) -Force | Out-Null diff --git a/chezmoi/dot_codex/dot_env b/chezmoi/dot_codex/dot_env new file mode 100644 index 0000000..1c23086 --- /dev/null +++ b/chezmoi/dot_codex/dot_env @@ -0,0 +1,12 @@ +HTTP_PROXY=http://hproxy.local:12334 +HTTPS_PROXY=http://hproxy.local:12334 +ALL_PROXY=socks5://hproxy.local:12334 +NO_PROXY=hproxy.local,localhost,127.0.0.1,::1,[::1],.concept-software.ru + +http_proxy=http://hproxy.local:12334 +https_proxy=http://hproxy.local:12334 +all_proxy=socks5://hproxy.local:12334 +no_proxy=hproxy.local,localhost,127.0.0.1,::1,[::1],.concept-software.ru + +WSLENV=HTTP_PROXY/u:HTTPS_PROXY/u:ALL_PROXY/u:NO_PROXY/u:http_proxy/u:https_proxy/u:all_proxy/u:no_proxy/u +NODE_USE_ENV_PROXY=1 diff --git a/chezmoi/dot_local/bin/start-claude-proxy.vbs b/chezmoi/dot_local/bin/start-claude-proxy.vbs new file mode 100644 index 0000000..fd57a34 --- /dev/null +++ b/chezmoi/dot_local/bin/start-claude-proxy.vbs @@ -0,0 +1,28 @@ +Option Explicit + +Dim fileSystem +Dim launcherPath +Dim powerShellPath +Dim command +Dim exitCode +Dim shell + +Set fileSystem = CreateObject("Scripting.FileSystemObject") +Set shell = CreateObject("WScript.Shell") + +launcherPath = shell.ExpandEnvironmentStrings("%USERPROFILE%\.local\bin\start-claude-proxy.ps1") +powerShellPath = shell.ExpandEnvironmentStrings("%LOCALAPPDATA%\Microsoft\WindowsApps\pwsh.exe") + +If Not fileSystem.FileExists(powerShellPath) Then + powerShellPath = "pwsh.exe" +End If + +command = """" & powerShellPath & _ + """ -NoLogo -NoProfile -ExecutionPolicy Bypass -File """ & _ + launcherPath & """" + +exitCode = shell.Run(command, 0, True) +If exitCode <> 0 Then + MsgBox "Не удалось запустить Claude Proxy. Код ошибки: " & exitCode, _ + vbCritical, "Claude Proxy" +End If diff --git a/chezmoi/dot_local/bin/start-codex-proxy.ps1 b/chezmoi/dot_local/bin/start-codex-proxy.ps1 index b3be928..5e2b3bf 100644 --- a/chezmoi/dot_local/bin/start-codex-proxy.ps1 +++ b/chezmoi/dot_local/bin/start-codex-proxy.ps1 @@ -3,52 +3,8 @@ $ErrorActionPreference = 'Stop' $ProxyHostName = 'hproxy.local' $ProxyPort = 12334 $HttpProxy = "http://${ProxyHostName}:${ProxyPort}" -$SocksProxy = "socks5://${ProxyHostName}:${ProxyPort}" -$NoProxy = "${ProxyHostName},localhost,127.0.0.1,::1,[::1],.concept-software.ru" $ProxyBypassList = "${ProxyHostName};localhost;127.0.0.1;[::1];*.concept-software.ru" -function Set-ProxyEnvironment { - $env:HTTP_PROXY = $HttpProxy - $env:HTTPS_PROXY = $HttpProxy - $env:ALL_PROXY = $SocksProxy - $env:NO_PROXY = $NoProxy - - $env:http_proxy = $HttpProxy - $env:https_proxy = $HttpProxy - $env:all_proxy = $SocksProxy - $env:no_proxy = $NoProxy -} - -function Add-WslEnvEntries { - $RequiredEntries = @( - 'HTTP_PROXY/u', - 'HTTPS_PROXY/u', - 'ALL_PROXY/u', - 'NO_PROXY/u', - 'http_proxy/u', - 'https_proxy/u', - 'all_proxy/u', - 'no_proxy/u' - ) - - $Entries = New-Object System.Collections.Generic.List[string] - if (-not [string]::IsNullOrWhiteSpace($env:WSLENV)) { - foreach ($Entry in ($env:WSLENV -split ':')) { - if (-not [string]::IsNullOrWhiteSpace($Entry) -and -not $Entries.Contains($Entry)) { - [void]$Entries.Add($Entry) - } - } - } - - foreach ($Entry in $RequiredEntries) { - if (-not $Entries.Contains($Entry)) { - [void]$Entries.Add($Entry) - } - } - - $env:WSLENV = [string]::Join(':', $Entries) -} - function Get-CodexApplication { $Package = Get-AppxPackage -Name 'OpenAI.Codex' -ErrorAction SilentlyContinue | Select-Object -First 1 @@ -74,6 +30,21 @@ function Get-CodexApplication { } } +function Assert-CodexNotRunning { + param( + [Parameter(Mandatory)] + [string]$Executable + ) + + $RunningProcess = Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | + Where-Object { $_.ExecutablePath -eq $Executable } | + Select-Object -First 1 + + if ($null -ne $RunningProcess) { + throw 'Codex уже запущен. Полностью закройте приложение и повторно откройте ярлык Codex Proxy.' + } +} + function Start-CodexApplication { param( [Parameter(Mandatory)] @@ -137,15 +108,17 @@ namespace CodexProxyLauncher '@ } - [void][CodexProxyLauncher.ApplicationActivator]::Activate( + [CodexProxyLauncher.ApplicationActivator]::Activate( $AppUserModelId, $Arguments ) } -Set-ProxyEnvironment -Add-WslEnvEntries - $CodexApplication = Get-CodexApplication +Assert-CodexNotRunning -Executable $CodexApplication.Executable + $CodexArguments = "--proxy-server=${HttpProxy} --proxy-bypass-list=${ProxyBypassList}" -Start-CodexApplication -AppUserModelId $CodexApplication.AppUserModelId -Arguments $CodexArguments +Start-CodexApplication ` + -AppUserModelId $CodexApplication.AppUserModelId ` + -Arguments $CodexArguments | + Out-Null