User report: on a system with pre-existing legacy claude-code v2.1.112
(cli.js layout), running uclaude_install.sh announced
"SEA install complete: v2.1.120"
"Patch status: patched"
"Update complete."
yet `claude --version` still showed 2.1.112. Root cause:
1. ensure_claude_code() ran `npm install -g @anthropic-ai/claude-code@2.1.120`
but npm refused to overwrite existing layout cleanly — registered as success
but cli.js stayed in place.
2. SEA install in /usr/lib/.../@anthropic-ai/claude-code/ also succeeded, but
`which claude` still resolved to ~/.npm-global/bin/claude → legacy cli.js
because that prefix wins on PATH.
3. Updater's get_installed_version() found legacy cli.js first, reported 2.1.112.
Three fixes:
A. ensure_claude_code() now runs `npm uninstall -g @anthropic-ai/claude-code`
before install when a legacy cli.js is detected, then runs install with
--force. This guarantees clean SEA layout.
B. After successful SEA install, walk find_all_cli_js() and rename any
surviving cli.js → .legacy.bak. PATH resolution can no longer pick
stale cli.js over /usr/bin/claude.
C. Hard verification: spawn `/usr/bin/claude --version` (absolute path,
bypassing PATH cache) and assert it matches the version we just
installed. Any mismatch surfaces a WARN with diagnostic message
pointing user at `which claude` to investigate further.
After this fix the same install flow on the user's machine will report
v2.1.120 and `claude --version` will agree. All 9 SEA patches (including
bypass_permissions_prompt = YOLO mode and root_check_removed) remain
applied — they're baked into releases/v2.1.120/sea/claude (sha256
eb126100a6913a9e56884743df22f99d549aa69a5f76dce6486b90442508407e).
Picker /model showed only 4 models even though settings.availableModels had 19.
Root cause was a second filter in the bundle that ae1 didn't catch — see
claude_code_patcher commit for full analysis.
New binary applies 8 patches (was 7), including ae2 to remove the
`startsWith("anthropic.")` predicate so all custom models pass through.
binary_sha256: 0cc8906fddea3c6c9a1829d402069cafb0d8433d5bf1097645bbbef6a2f3b7b2 (was ac6f09b8)
size: unchanged (245,230,208 bytes — same-length byte patch)
wrapper: unchanged
After re-running uclaude_install.sh, /model picker should display all 19
models from settings.availableModels.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Root cause of "/model picker shows only 5 models": Anthropic removed
the CLAUDE_CUSTOM_MODELS env var sometime around v2.1.114. The picker
now reads exclusively from settings.json `availableModels` (a Zod-typed
allowlist field). We were:
- Writing CLAUDE_CUSTOM_MODELS into env.* (no longer read)
- Calling data.pop("availableModels", None) — actively REMOVING the
field that the picker now needs
So the picker fell back to built-in models + the two ANTHROPIC_DEFAULT_*
models, giving exactly 4 entries. Confirmed via strings on the v2.1.119
SEA binary: zero hits for "CLAUDE_CUSTOM_MODELS", but Zod schema
defines availableModels as the model allowlist.
Fix:
- patch_user() writes config['models'] into data['availableModels']
(still also sets the env var for backward-compat with side-by-side
older binaries)
- Verification block in install.sh + updater.py now reports both:
availableModels: N models (env.CLAUDE_CUSTOM_MODELS legacy: N)
Tested locally on v2.1.119 SEA install → settings.json now contains
availableModels with all 19 models. Restart claude → /model should show
the full list.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
After upstream switched to SEA (Single Executable Application) layout
in v2.1.114+, there is no cli.js anymore — only bin/claude.exe.
Before this fix:
- find_cli_js() searched only for cli.js → returned None on SEA installs
- get_installed_version() returned (None, None) → "Claude Code: not installed"
- is_patched() returned (False, [3 markers]) → false-negative even after
successful patch
- cmd_check showed "not installed" right after a successful update
- cmd_update would loop reinstalling because patch markers seemed missing
This contributed to a user-facing incident where /model picker showed
only built-in models even though CLAUDE_CUSTOM_MODELS was set in
settings.json: the binary update path was triggering uninstall+reinstall
cycles instead of being recognised as already-patched.
Changes:
- New find_claude_artifact() finds either cli.js or bin/claude.exe,
including the deeply-nested layout npm uses for SEA wrapper packages
- find_all_cli_js() returns both legacy and SEA artifacts
- is_patched() auto-detects layout: text scan for cli.js, bytes scan
for claude.exe (markers: /*ae1_models_filter_patched*/,
/*bypass_permissions_prompt*/)
- get_installed_version() reads package.json next to bin/ for SEA
- uclaude_install.sh adds binary marker verification at end of install
so users immediately see if the SEA payload was patched
Tests: new tests/test_sea_detect.py covers all 4 detector functions
against fake SEA install layouts (including nested form). All 20 tests
pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Per user demand after data loss incident: never trust mode flags alone.
Previously only `full` mode created tar.gz backup. Now `safe` and
`settings-only` also create full tar.gz of ~/.claude (resp .codex,
.gemini, .qwen) BEFORE any mutation. If backup fails, refuse to
proceed for that user — skip to next.
Restore is always one command:
tar -xzf ~/.<tool>.uninstall-backup.<TS>.tar.gz -C ~
Applies to all 4 scripts: uclaude, ucodex, ugemini, uqwen.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
After user lost 6 months of work to `rm -rf ~/.claude`, ALL 4 uninstall
scripts (claude, codex, gemini, qwen) now require explicit choice:
Modes:
1) safe (default) — remove binary + env + settings.json
KEEP projects, history, commands(skills),
plans, file-history, plugins
2) settings-only — clear settings.json only, keep binary + data
3) full — wipe everything (tar backup first, requires
typing 'WIPE' to confirm)
4) cancel — exit, do nothing
Default flow:
- Interactive prompt with PREVIEW of user data (size, project count,
command count, history line count) before any destructive op
- Cancel option always available
- Each file backed up to *.uninstall.bak.<TS> before removal
- /etc/environment + .bashrc + /etc/profile.d backed up before sed
Non-interactive (CI / scripts):
UCLAUDE_MODE=safe sudo bash uclaude_uninstall.sh
UCLAUDE_MODE=full sudo bash uclaude_uninstall.sh # creates tar backup
UCLAUDE_YES=1 # skip prompt, default to safe mode
NEVER again should an uninstaller silently destroy user data.
Per-tool env vars: UCLAUDE_MODE / UCODEX_MODE / UGEMINI_MODE / UQWEN_MODE.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
User reported losing 6 months of accumulated work — projects, plans,
custom commands/skills, file-history, history.jsonl — because
uclaude_uninstall.sh did `rm -rf ~/.claude` without warning or backup.
Same destruction risk in codex/gemini/qwen uninstallers (each has its
own ~/.tool-name/ dir with user data).
Fix:
- claude/uclaude_uninstall.sh: DEFAULT preserves projects/, history.jsonl,
commands/, plans/, file-history/, plugins/. Only removes settings.json
+ cache/ (which Claude regenerates). settings.json backed up first.
- Explicit opt-in to wipe everything: UCLAUDE_PURGE_USER_DATA=1
(and even then creates a tar backup before delete)
- README guidance updated
NEVER again should an uninstaller silently destroy user data.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
User reported: after install, claude /model picker shows only 5 models
(built-ins) instead of 19 — config DID land somewhere but CLAUDE_CUSTOM_
MODELS env block in settings.json was empty/missing.
Hard to debug without seeing user's settings.json. Add verbose diagnostic:
uclaude_updater.py patch_all_users():
- Pre-check: warn if config has 0 models OR placeholder api_key
- Post-patch per user: read back the JUST-WRITTEN settings.json, count
CLAUDE_CUSTOM_MODELS entries, print:
"Patched root: /root/.claude/settings.json (env.CLAUDE_CUSTOM_MODELS=19 models)"
uclaude_install.sh — final verification block:
- Show ANTHROPIC_BASE_URL + AUTH_TOKEN prefix + custom_models count
- Loud warning if 0 models or auth_token missing
Now user can immediately see "0 models" or "19 models" without manually
inspecting settings.json. If 0 — knows config fetch failed silently.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
User hit two bugs in production:
1. uclaude_install.sh ERROR: Command failed at line 82 — gitea returned
transient HTTP 502 to `git fetch`, `2>/dev/null` masked stderr but
ERR trap fired with cryptic message.
2. After install, claude model picker showed only 5 models (built-in
defaults) instead of 19. Root cause: load_config() fell back to the
PUBLIC sanitized patcher.config.json (api_key='YOUR_API_KEY') after
remote fetch failed → claude API auth broken → custom models invisible.
Fixes:
claude/uclaude_install.sh:
- New retry_git() helper: 3 attempts, 5s backoff, loud diagnostic
- Existing-clone branch: retry_git wraps `git fetch` AND `git reset`
- Fallback: if fetch fails 3x on existing clone, nuke and re-clone fresh
(incremental fetch breaks more often than full clone on flaky gitea)
- Secondary fetch (before updater): tolerates failure with `|| true`
(we already have a working clone)
claude/uclaude_updater.py:
- _config_is_usable() guard: rejects {"api_key": "YOUR_API_KEY"} etc.
- load_config() retries remote 3x with backoff before falling back
- Removed local-file fallback (was loading public sanitized = bait)
- Cache-only fallback now (from previous successful fetch)
Public configs synced from canonical (api_key sanitized, models list
fully refreshed):
- claude/patcher.config.json: 17 → 19 models (+gpt-5.5, +gemini-3.1-pro etc)
- codex/codex_config.json: 4 → 5 models (+gpt-5.5)
- gemini/gemini_config.json: refreshed
- target_version: 2.1.112 → 2.1.119
Tests: tests/test_installer_robustness.py — 6 new GREEN guards.
Total: 196 → 207 GREEN.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Mirrors claude_code_patcher@661eced — fixes Windows ucodex_install.ps1
crash 'Error loading config.toml: missing assignment' caused by
toml_value(dict) emitting Python str(dict) instead of TOML syntax.
Existing broken installs: re-run installer or manually delete the bad
section from ~/.codex/config.toml then re-run ucodex_install.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
CRITICAL: api_key 'ClauderAPI2' was committed to PUBLIC unlimitedcoding
repo (private:False on gitea) in 4 *_config.json + 8 ps1 scripts. Anyone
on the internet could read it via curl with no auth (HTTP 200 raw access).
This commit:
1. Sanitizes 4 *_config.json: api_key → "YOUR_API_KEY" + _note pointing
users to private config repo for production credentials.
2. Removes 'ClauderAPI2' literal from 8 ps1 installer/updater scripts
(claude/codex/gemini/qwen × install/update). Each script now has a
sanitized block at top that fetches api_key from private
unlimitedcoding-config repo at runtime via Authorization token.
3. Switches 6 sh installer scripts from public REPO_RAW to PRIVATE
unlimitedcoding-config base URL for *_config.json downloads.
4. Removes stale .patcher.config.cache.json (will regen on next install).
Production configs MOVED to private repo (separate commit e839102 on
unlimitedcoding-config/main).
KNOWN UNCHANGED:
- releases/v2.1.119/sea/cli-wrapper.cjs still has api_key (part of npm
package distribution; clients need it locally; sensey serves same).
- Read-only gitea token (cadffcb0...) remains in installers — needed
for token-auth fetch from private repo. Scoped read-only.
RECOMMEND: api_key rotation in proxy auth list because ClauderAPI2 was
publicly exposed for an unknown period. Existing client installs would
need re-install or env override.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
User reported on Mac/Win:
1. gpt-5.5 not appearing in client model picker after install
2. codex CLI not installed by uclaude_install.{sh,ps1}
Root causes (TDD verified):
1. ps1 hardcoded fallback (when private config fetch fails) had only 5
models without gpt-5.5; users behind firewall/with stale cache fall
back to it. Updated fallback to include latest list including gpt-5.5,
gemini-3.1-pro, gemini-3-flash, glm-5.1.
2. Codex has SEPARATE installer (codex/ucodex_install.{sh,ps1}). Users
following claude install instructions miss it. README documents both
but as separate steps. Now uclaude_install.{sh,ps1} optionally chain
to codex installer at the end (skip via UCLAUDE_SKIP_CODEX=1).
Sh installer: also expanded sparse-checkout to include codex/ directory.
README versions: bumped Codex CLI 0.122.0 → 0.125.0 in all 4 locale files
(README.md, README_ru.md, README_es.md, README_zh.md).
3 new tests in claude_code_patcher/tests/test_installers_completeness.py
verify the fix sticks (ps1 fallback has gpt-5.5, both installers mention
codex chain, README codex version current via GitHub API check).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Auth conflict warning fix: setting both ANTHROPIC_AUTH_TOKEN and
ANTHROPIC_API_KEY simultaneously triggers Anthropic CLI to print
"Auth conflict" on every claude invocation. Drop API_KEY (we never
needed both — AUTH_TOKEN is the canonical for our proxy).
Best-effort cleanup: clear stale ANTHROPIC_API_KEY from User env (set
by previous installer versions).
Models stale fix: hardcoded list (qwen3-coder-plus, gemini-3.1-pro-preview,
glm-5, glm-4.7 etc.) was missing latest gemini-3.1-pro, gemini-3-flash,
glm-5.1. Now fetches CLAUDE_CUSTOM_MODELS from the private config repo
(unlimitedcoding-config/patcher.config.json) at install time, with
fallback to a small known-good list if fetch fails.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
One-liner script that:
- Verifies/installs Node.js >= 18, git, codex CLI
- Adds 'openai-codex' marketplace (github.com/openai/codex-plugin-cc)
- Installs/updates 'codex@openai-codex' plugin
- Verifies result via 'claude plugin list'
Re-runs are safe — auto-detects what is already installed and only fills
gaps or pulls newer plugin versions.
Three platforms covered: Linux (apt/dnf/yum), macOS (brew),
Windows (winget) via .sh and .ps1 wrappers + CMD entry-point.
Plugin commands inside Claude Code:
/codex:review, /codex:adversarial-review, /codex:rescue,
/codex:status, /codex:result, /codex:cancel
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- claude-haiku-4-5-20251001: was available in proxy but missing from config
- glm-5.1: new Zhipu model leading SWE-Bench Pro (Apr 2026), now registered
in proxy registry and reachable via /v1/messages
All previously listed models kept (qwen3.6-coder-* tokens are temporarily
expired but will recover once tokens refresh).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Windows PowerShell 5.1 reads .ps1 files without BOM as Windows-1251 by
default. Em-dashes (-) and other Unicode chars in string literals get
mangled into invalid bytes (e.g. "session - no" becomes garbage that
breaks the parser with "Unexpected token" errors.
Replaced em-dash, en-dash, smart quotes, ellipsis, NBSP and arrows with
their ASCII equivalents across all 12 .ps1 scripts (install/update/
uninstall for claude/gemini/codex/qwen).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Previously env vars were only set inside the PowerShell-fallback branch
(when Python was missing). If Python was present, gemini_patcher.py wrote
env vars via setx — which only updates the registry, not the current
PowerShell process. Result: user runs update, then `gemini`, and gets
prompted for API key because process.env.GEMINI_API_KEY is empty.
Fix: always set env vars in BOTH User scope (persistent across sessions)
AND $env: (current session) at the end of the script, regardless of which
branch was taken. Also fix malformed JSON in trustedFolders.json fallback
(escaped quotes were inconsistent).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Qwen patcher had two issues:
1. Only patched dashscope.aliyuncs.com but missed regional endpoints
(cn-hongkong, dashscope-intl, dashscope-us). Users in those regions
would still hit Aliyun directly.
2. --validate raised ModuleNotFoundError (referenced removed updater/
package). Replaced with self-contained inline checker — 13 GREEN
targets covering cli.js markers, settings.json, env vars.
Also bump Codex version to v0.122.0 across all READMEs (was v0.116.0).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
User feedback: pasting bash heredocs into PowerShell fails. Make the
ugemini_install.ps1/.sh wrapper the one and only command users need —
no need to copy bash/PS code blocks. Wrapper handles Node.js, npm,
env vars, settings.json, trustedFolders.json automatically.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Users were copying bash heredocs (cat << EOF) into PowerShell where they fail.
Split into three explicit sections per shell with warning at top.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>