Skip to content

Commit b67a697

Browse files
committed
Fix cross-platform auth prep and skill links
Switch ChatGPT-login provider auth prep to a proxy-managed provider-auth.json file while preserving the env-var compatibility path. Delegate skill link creation/removal to the manager so .codex install/update/uninstall flows work across Windows and POSIX shells. Fixes #2 Fixes #3
1 parent 373c9fe commit b67a697

14 files changed

Lines changed: 853 additions & 248 deletions

File tree

.codex/INSTALL.md

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,56 +12,65 @@ Fetch and follow instructions from https://raw.githubusercontent.com/gaoguobin/c
1212

1313
## What this installs
1414

15-
- Git repo: `%USERPROFILE%\.codex\codex-fast-proxy`
15+
- Git repo: `~/.codex/codex-fast-proxy`
1616
- Python package: editable user install of `codex-fast-proxy`
17-
- Skill namespace junction: `%USERPROFILE%\.agents\skills\codex-fast-proxy -> %USERPROFILE%\.codex\codex-fast-proxy\skills`
18-
- Runtime state after enable: `%USERPROFILE%\.codex\codex-fast-proxy-state`
19-
- Startup hook after enable: `%USERPROFILE%\.codex\hooks.json`
17+
- Skill namespace link: `~/.agents/skills/codex-fast-proxy -> ~/.codex/codex-fast-proxy/skills`
18+
- Runtime state after enable: `~/.codex/codex-fast-proxy-state`
19+
- Startup hook after enable: `~/.codex/hooks.json`
2020

2121
## Install steps
2222

2323
This install only installs files and the skill. It must not switch Codex App to the proxy.
2424
The startup hook is installed later by `python -m codex_fast_proxy install --start`, not by this file-only install.
2525

26-
If the Codex environment uses sandbox or approval controls, request approval/escalation for the install block because it clones from GitHub, installs a Python package, writes under `%USERPROFILE%\.codex`, and creates a junction under `%USERPROFILE%\.agents`.
26+
If the Codex environment uses sandbox or approval controls, request approval/escalation for the install block because it clones from GitHub, installs a Python package, writes under `~/.codex`, and creates a skill link under `~/.agents`.
2727

28-
If any command fails because of network, permissions, sandbox write limits, or junction creation, do not try unrelated workarounds. Ask for approval and rerun the same intended install step.
28+
If any command fails because of network, permissions, sandbox write limits, or skill link creation, do not try unrelated workarounds. Ask for approval and rerun the same intended install step.
2929

3030
Run this PowerShell block exactly:
3131

3232
```powershell
33-
$repoRoot = Join-Path $HOME '.codex\codex-fast-proxy'
34-
$skillsRoot = Join-Path $HOME '.agents\skills'
33+
$pythonCmd = if (Get-Command python -ErrorAction SilentlyContinue) {
34+
'python'
35+
} elseif (Get-Command python3 -ErrorAction SilentlyContinue) {
36+
'python3'
37+
} else {
38+
throw 'Python 3 is required before installing codex-fast-proxy.'
39+
}
40+
$repoRoot = Join-Path (Join-Path $HOME '.codex') 'codex-fast-proxy'
41+
$skillsRoot = Join-Path (Join-Path $HOME '.agents') 'skills'
3542
$skillNamespace = Join-Path $skillsRoot 'codex-fast-proxy'
3643
3744
if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
3845
throw 'git is required before installing codex-fast-proxy.'
3946
}
4047
41-
if (-not (Get-Command python -ErrorAction SilentlyContinue)) {
42-
throw 'python is required before installing codex-fast-proxy.'
43-
}
44-
4548
if (Test-Path $repoRoot) {
4649
throw 'codex-fast-proxy is already installed. Follow UPDATE.md instead.'
4750
}
4851
4952
if (Test-Path $skillNamespace) {
50-
throw 'The skill namespace junction already exists. Remove it or follow UNINSTALL.md before reinstalling.'
53+
throw 'The skill namespace link already exists. Remove it or follow UNINSTALL.md before reinstalling.'
5154
}
5255
53-
New-Item -ItemType Directory -Force -Path $skillsRoot | Out-Null
5456
git clone https://github.com/gaoguobin/codex-fast-proxy.git $repoRoot
55-
python -m pip install --user -e $repoRoot
56-
cmd /d /c "mklink /J `"$skillNamespace`" `"$repoRoot\skills`""
57+
& $pythonCmd -m pip install --user -e $repoRoot
58+
& $pythonCmd -m codex_fast_proxy link-skill --repo-root $repoRoot
5759
```
5860

5961
## After install
6062

6163
Run this check in the same Codex turn:
6264

6365
```powershell
64-
python -m codex_fast_proxy doctor
66+
$pythonCmd = if (Get-Command python -ErrorAction SilentlyContinue) {
67+
'python'
68+
} elseif (Get-Command python3 -ErrorAction SilentlyContinue) {
69+
'python3'
70+
} else {
71+
throw 'Python 3 is required before checking codex-fast-proxy.'
72+
}
73+
& $pythonCmd -m codex_fast_proxy doctor
6574
```
6675

6776
Report the JSON result in the reply. When `"ok": true`, explicitly tell the user:
@@ -86,22 +95,23 @@ Codex App/CLI Fast UI choices; in API-key mode it may inject the priority tier w
8695
`--service-tier-policy inject_missing` only when the user explicitly asks for global Fast injection,
8796
and `--service-tier-policy preserve` only when they explicitly want no proxy-side Fast injection. If
8897
the user wants ChatGPT login compatibility for plugins/GitHub/Apps/connectors while model requests
89-
still use a third-party provider, configure an upstream key environment variable with
90-
`--upstream-api-key-env <ENV_NAME>`; do not ask the user to paste API keys into chat and do not edit
91-
`auth.json` unless they explicitly request recovery. This auth override applies only to provider API
98+
still use a third-party provider, prepare the proxy provider auth file with
99+
`prepare-chatgpt-login`, then use `set-upstream --use-provider-auth-file`; do not ask the user to
100+
paste API keys into chat and do not edit `auth.json` unless they explicitly request recovery. This
101+
auth override applies only to provider API
92102
requests that already go through the local proxy; it must not intercept or modify ChatGPT
93103
plugin/GitHub/App connector traffic. In override mode, the proxy replaces provider `Authorization`
94104
and drops unexpected `Cookie` headers before forwarding upstream.
95105

96106
If Codex currently works through a third-party provider and the user wants to prepare for ChatGPT
97107
login, run `python -m codex_fast_proxy prepare-chatgpt-login` first as a dry run. Report the
98108
non-secret JSON fields, then ask before running `python -m codex_fast_proxy prepare-chatgpt-login
99-
--target-env <ENV_NAME> --apply`. The apply step writes the provider key through the Windows user
100-
environment API, does not print the key, does not change proxy settings, and does not edit
101-
`auth.json`. After apply, run `python -m codex_fast_proxy set-upstream --upstream-api-key-env
102-
<ENV_NAME>` so the manager verifies `POST /v1/responses` with `stream=true` before saving the auth
103-
split. Tell the user to restart Codex App or open a new CLI process after any user environment
104-
variable change.
109+
--apply`. The apply step copies the currently working provider key into
110+
`~/.codex/codex-fast-proxy-state/provider-auth.json`, does not print the key, does not change proxy
111+
settings, and does not edit `auth.json`. After apply, run
112+
`python -m codex_fast_proxy set-upstream --use-provider-auth-file` so the manager verifies
113+
`POST /v1/responses` with `stream=true` before saving the auth split. Tell the user to restart Codex
114+
App or open a new CLI process if the result reports `needs_restart=true`.
105115

106116
After a successful `install --start`, report the non-secret top-level `next_user_action` and
107117
`chatgpt_login_hint` fields. When `chatgpt_login_hint.status=optional_setup_available`, tell the

.codex/SET_UPSTREAM.md

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,34 @@ not required. If they want to change provider URL and did not provide the new up
1212
it. Do not guess provider URLs.
1313

1414
If the Codex environment uses sandbox or approval controls, request approval/escalation because this
15-
flow may write under `%USERPROFILE%\.codex`, edit `%USERPROFILE%\.codex\hooks.json`, restart the
15+
flow may write under `~/.codex`, edit `~/.codex/hooks.json`, restart the
1616
background proxy, and update the uninstall recovery baseline.
1717

18+
Every PowerShell block below assumes this resolver has already run in the same shell:
19+
20+
```powershell
21+
$pythonCmd = if (Get-Command python -ErrorAction SilentlyContinue) {
22+
'python'
23+
} elseif (Get-Command python3 -ErrorAction SilentlyContinue) {
24+
'python3'
25+
} else {
26+
throw 'Python 3 is required before changing codex-fast-proxy settings.'
27+
}
28+
```
29+
1830
Run this block after replacing `<UPSTREAM_BASE_URL>` with the user-provided URL:
1931

2032
```powershell
21-
$statusJson = python -m codex_fast_proxy status
33+
$statusJson = & $pythonCmd -m codex_fast_proxy status
2234
$status = $statusJson | ConvertFrom-Json
2335
if ($status.config_matches -ne $true) {
2436
$statusJson
2537
throw 'Codex config no longer points to the recorded local proxy. Review ~/.codex/config.toml before changing upstream.'
2638
}
2739
28-
$resultJson = python -m codex_fast_proxy set-upstream --upstream-base '<UPSTREAM_BASE_URL>'
40+
$resultJson = & $pythonCmd -m codex_fast_proxy set-upstream --upstream-base '<UPSTREAM_BASE_URL>'
2941
$resultJson
30-
python -m codex_fast_proxy status
42+
& $pythonCmd -m codex_fast_proxy status
3143
```
3244

3345
`set-upstream` verifies the candidate route before writing settings by sending one side-path
@@ -39,78 +51,79 @@ may be unable to reach the model.
3951
If the user asks to verify first without changing local state, run:
4052

4153
```powershell
42-
python -m codex_fast_proxy verify-upstream --upstream-base '<UPSTREAM_BASE_URL>'
54+
& $pythonCmd -m codex_fast_proxy verify-upstream --upstream-base '<UPSTREAM_BASE_URL>'
4355
```
4456

4557
Report the JSON result and stop. `verify-upstream` must not write settings, edit Codex config,
4658
install hooks, or restart the proxy.
4759

48-
For ChatGPT login compatibility without changing the upstream URL, ask for the environment variable
49-
name that already contains the third-party provider API key. Do not ask the user to paste the key
50-
value into chat. This affects only provider API requests that already go through the local proxy; it
60+
For ChatGPT login compatibility without changing the upstream URL, prepare the proxy provider auth
61+
file. Do not ask the user to paste the key value into chat. This affects only provider API requests
62+
that already go through the local proxy; it
5163
must not intercept ChatGPT plugin/GitHub/App connector traffic. In override mode, the proxy replaces
5264
provider `Authorization` and drops unexpected `Cookie` headers before forwarding upstream.
5365

54-
If the user does not already have a provider key environment variable, run a dry run first:
66+
Run a dry run first:
5567

5668
```powershell
57-
python -m codex_fast_proxy prepare-chatgpt-login
69+
& $pythonCmd -m codex_fast_proxy prepare-chatgpt-login
5870
```
5971

6072
Report only the non-secret JSON fields. If the dry run found the current working provider key in
6173
`auth.json` or the environment, ask before applying:
6274

6375
```powershell
64-
python -m codex_fast_proxy prepare-chatgpt-login --target-env '<ENV_NAME>' --apply
76+
& $pythonCmd -m codex_fast_proxy prepare-chatgpt-login --apply
6577
```
6678

67-
The apply step writes a Windows user environment variable through the manager, does not print the
68-
key, and does not change proxy settings. After it succeeds, continue with `set-upstream` so the
69-
manager verifies a streaming `/v1/responses` request before saving the auth override.
79+
The apply step copies the current working provider key into
80+
`~/.codex/codex-fast-proxy-state/provider-auth.json`, does not print the key, and does not change
81+
proxy settings. After it succeeds, continue with `set-upstream` so the manager verifies a streaming
82+
`/v1/responses` request before saving the auth override.
7083

7184
```powershell
72-
$statusJson = python -m codex_fast_proxy status
85+
$statusJson = & $pythonCmd -m codex_fast_proxy status
7386
$status = $statusJson | ConvertFrom-Json
7487
if ($status.config_matches -ne $true) {
7588
$statusJson
7689
throw 'Codex config no longer points to the recorded local proxy. Review ~/.codex/config.toml before changing upstream auth.'
7790
}
7891
79-
$resultJson = python -m codex_fast_proxy set-upstream --upstream-api-key-env '<ENV_NAME>'
92+
$resultJson = & $pythonCmd -m codex_fast_proxy set-upstream --use-provider-auth-file
8093
$resultJson
81-
python -m codex_fast_proxy status
94+
& $pythonCmd -m codex_fast_proxy status
8295
```
8396

84-
To clear a previously configured upstream auth environment override and return to preserving Codex's
85-
original provider `Authorization` header, run:
97+
To clear a previously configured upstream auth override and return to preserving Codex's original
98+
provider `Authorization` header, run:
8699

87100
```powershell
88-
python -m codex_fast_proxy set-upstream --clear-upstream-api-key-env
89-
python -m codex_fast_proxy status
101+
& $pythonCmd -m codex_fast_proxy set-upstream --clear-upstream-auth
102+
& $pythonCmd -m codex_fast_proxy status
90103
```
91104

92105
For explicit global Fast injection without changing the upstream URL, confirm that the user accepts
93106
that Codex App's Fast UI toggle will no longer control requests whose `service_tier` is missing, then
94107
run:
95108

96109
```powershell
97-
python -m codex_fast_proxy set-upstream --service-tier-policy inject_missing
98-
python -m codex_fast_proxy status
110+
& $pythonCmd -m codex_fast_proxy set-upstream --service-tier-policy inject_missing
111+
& $pythonCmd -m codex_fast_proxy status
99112
```
100113

101114
To return to UI-controlled Fast behavior, run:
102115

103116
```powershell
104-
python -m codex_fast_proxy set-upstream --service-tier-policy preserve
105-
python -m codex_fast_proxy status
117+
& $pythonCmd -m codex_fast_proxy set-upstream --service-tier-policy preserve
118+
& $pythonCmd -m codex_fast_proxy status
106119
```
107120

108121
For the default automatic behavior, where API-key mode can use global priority but ChatGPT-login or
109122
unclear states preserve the App/CLI choice, run:
110123

111124
```powershell
112-
python -m codex_fast_proxy set-upstream --service-tier-policy auto
113-
python -m codex_fast_proxy status
125+
& $pythonCmd -m codex_fast_proxy set-upstream --service-tier-policy auto
126+
& $pythonCmd -m codex_fast_proxy status
114127
```
115128

116129
Report the set-upstream JSON and the final status JSON. The key fields are `provider`, `base_url`,
@@ -139,7 +152,6 @@ net start winnat
139152
netsh interface ipv4 show excludedportrange protocol=tcp
140153
```
141154

142-
If the user changed API key environment variables, model, reasoning, or other Codex config, tell
143-
them to restart Codex App or open a new CLI process so Codex reloads those settings. The proxy can
144-
read Windows user environment variables directly when possible, but already-running Codex processes
155+
If the user changed provider auth, model, reasoning, or other Codex config, tell them to restart
156+
Codex App or open a new CLI process so Codex reloads those settings. Already-running Codex processes
145157
still may need a restart to reload their own config and environment.

.codex/UNINSTALL.md

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,21 @@ If the user changed `~/.codex/config.toml` after enabling the proxy, the manager
1616

1717
Uninstall removes only the `codex-fast-proxy` entry from `~/.codex/hooks.json`; unrelated user hooks must be preserved.
1818

19-
If the Codex environment uses sandbox or approval controls, request approval/escalation for uninstall because it may restore `~/.codex/config.toml`, edit `~/.codex/hooks.json`, stop a background proxy, uninstall a Python package, remove a junction under `%USERPROFILE%\.agents`, and delete `%USERPROFILE%\.codex\codex-fast-proxy`.
19+
If the Codex environment uses sandbox or approval controls, request approval/escalation for uninstall because it may restore `~/.codex/config.toml`, edit `~/.codex/hooks.json`, stop a background proxy, uninstall a Python package, remove a skill link under `~/.agents`, and delete `~/.codex/codex-fast-proxy`.
2020

21-
If any command fails because of permissions, sandbox write limits, process locks, or junction removal, do not try unrelated workarounds. Ask for approval and rerun the same intended uninstall step.
21+
If any command fails because of permissions, sandbox write limits, process locks, or skill link removal, do not try unrelated workarounds. Ask for approval and rerun the same intended uninstall step.
2222

2323
Run this PowerShell block exactly:
2424

2525
```powershell
26-
$repoRoot = Join-Path $HOME '.codex\codex-fast-proxy'
27-
$skillNamespace = Join-Path $HOME '.agents\skills\codex-fast-proxy'
26+
$pythonCmd = if (Get-Command python -ErrorAction SilentlyContinue) {
27+
'python'
28+
} elseif (Get-Command python3 -ErrorAction SilentlyContinue) {
29+
'python3'
30+
} else {
31+
throw 'Python 3 is required before uninstalling codex-fast-proxy.'
32+
}
33+
$repoRoot = Join-Path (Join-Path $HOME '.codex') 'codex-fast-proxy'
2834
$uninstallJson = $null
2935
$uninstallResult = $null
3036
$status = $null
@@ -33,10 +39,10 @@ $confirmationRequired = $false
3339
3440
if (Test-Path $repoRoot) {
3541
$env:PYTHONPATH = Join-Path $repoRoot 'src'
36-
$statusJson = python -m codex_fast_proxy status
42+
$statusJson = & $pythonCmd -m codex_fast_proxy status
3743
$status = $statusJson | ConvertFrom-Json
3844
if ($status.config_matches -eq $true) {
39-
$uninstallJson = python -m codex_fast_proxy uninstall --defer-stop
45+
$uninstallJson = & $pythonCmd -m codex_fast_proxy uninstall --defer-stop
4046
$uninstallResult = $uninstallJson | ConvertFrom-Json
4147
$uninstallJson
4248
if ($uninstallResult.status -eq 'confirmation_required') {
@@ -47,7 +53,7 @@ if (Test-Path $repoRoot) {
4753
$deferred = $true
4854
}
4955
} else {
50-
$uninstallJson = python -m codex_fast_proxy uninstall
56+
$uninstallJson = & $pythonCmd -m codex_fast_proxy uninstall
5157
$uninstallResult = $uninstallJson | ConvertFrom-Json
5258
$uninstallJson
5359
if ($uninstallResult.status -eq 'confirmation_required') {
@@ -60,12 +66,13 @@ if (Test-Path $repoRoot) {
6066
}
6167
6268
if ((-not $deferred) -and (-not $confirmationRequired)) {
63-
python -m pip uninstall -y codex-fast-proxy
64-
65-
if (Test-Path $skillNamespace) {
66-
cmd /d /c "rmdir `"$skillNamespace`""
69+
if (Test-Path $repoRoot) {
70+
$env:PYTHONPATH = Join-Path $repoRoot 'src'
71+
& $pythonCmd -m codex_fast_proxy unlink-skill --repo-root $repoRoot
6772
}
6873
74+
& $pythonCmd -m pip uninstall -y codex-fast-proxy
75+
6976
if (Test-Path $repoRoot) {
7077
Remove-Item -LiteralPath $repoRoot -Recurse -Force
7178
}

0 commit comments

Comments
 (0)