Skip to content

U-Pool 0.5.0 — clean config writes, CodeFast, in-app updates

Choose a tag to compare

@U-C4N U-C4N released this 30 Jul 09:23
· 20 commits to main since this release

The fix

Switching provider used to merge into the target CLI's config: it swapped the keys U-Pool recognised and wrote everything else back. The Codex adapter only retired the [model_providers.<slug>] table named by previous, which came from U-Pool's own config.json — so it was empty whenever that had drifted from what was actually on disk (a fresh install over an existing setup, re-applying the same provider, a hand-edited file).

Leftovers from an earlier provider then sat next to the new one — an orphan provider table, a stale ANTHROPIC_AUTH_TOKEN, a leftover preferred_auth_method — and the CLI read the two as one contradictory configuration.

Both adapters now write from scratch. After a switch, ~/.claude/settings.json and ~/.codex/config.toml hold exactly the provider you picked and nothing else.

What that costs

hooks, statusLine, permissions.allow / deny, [mcp_servers.*] and your comments are removed. Nothing goes silently:

  • the toast after a switch names what went away
  • the previous version is copied into ~/.u-pool/backups/<app>/ as before
  • the first clean write also keeps a permanent *.pre-0.5.0.keep copy that the ten-deep rotation never prunes

~/.codex/auth.json is the one exception and is still merged key by key — it is a credential store, not a provider config, and rewriting it would drop a ChatGPT login U-Pool cannot recreate.

CodeFast

Presets for both apps: https://api.codefast.app/claude-api for Claude Code and https://api.codefast.app/codex-api/v1 for Codex.

The Codex preset uses env_key = "OPENAI_API_KEY" rather than the documented "codefast". Only that name can be written into auth.json, so the documented form would need a manual export and would ship a preset that does not work out of the box. Change it in the form if you prefer their version.

In-app updates

Settings → Updates checks the releases page at most once every six hours and remembers the answer, so an offline launch still knows. When something newer exists the Update button pulses; pressing it downloads the zip, checks it against the published length and SHA-256 and every member's CRC, unpacks it beside the install folder, and hands over to a small detached script that waits for U-Pool to exit, renames the old folder aside, renames the new one in — and undoes the first rename if the second fails.

Two situations are refused with an explanation and an Open release page button rather than half-applied: running from a source checkout, and an install under Program Files, where Windows will not let U-Pool replace itself without admin rights.

Also

  • Fixed a bundle that could never start. src/upool/__main__.py used a relative import, and PyInstaller runs it as a top-level __main__ with no package around it — so dist/U-Pool/U-Pool.exe died on launch with attempted relative import with no known parent package. scripts/build.py now starts the built exe once before packaging, so this cannot ship unnoticed again.
  • scripts/build.py emits U-Pool-<ver>-win64.zip and SHA256SUMS.txt — the assets the updater downloads.

Download

U-Pool-0.5.0-win64.zip — unzip anywhere you own (not Program Files, or in-app updates cannot replace the folder) and run U-Pool.exe.

SHA-256  e55cc22b4256585f11f026ec9172a9cf5c6ce7713cb63ba1bd6da528573b6f46