release 1.2.0: fresh-install fixes + compile/company-brain feature set - #370
Conversation
debian 12+ and ubuntu 23.04+ mark the system interpreter externally managed, so the installer's `pip install --user pipx` fallback is refused and the curl one-liner dead-ends on exactly the machines new users have — while the readme promises "never needs sudo". when the user-site install is refused, host pipx in a private venv under ~/.local/share/vouch/pipx-venv, symlink it into ~/.local/bin so later shells can still reach it, and continue. the sudo hint remains as the last resort (now also mentioning python3-venv, which the venv fallback needs on stock debian).
under LANG=en_US.ISO-8859-1 python encodes stdio with the locale codec, so the '•' and '…' glyphs in `vouch status` / `vouch search` output raise UnicodeEncodeError and the cli is unusable. kb artifacts are utf-8 on disk; the wire should speak utf-8 too. reconfigure stdin/stdout/stderr to utf-8 (errors="replace") at the cli group entry — this also covers the mcp/jsonl servers, which flow through the same entry point. terminals that genuinely can't render a glyph now see a replacement character instead of a traceback. also pin encoding="utf-8" on the last locale-dependent file i/o: config reads in capture.py and themes.py, and the migration rewriter's atomic_write_text. the regression test drives `python -m vouch status` in a subprocess with PYTHONIOENCODING=latin-1, which reproduces the failure without needing the host to have any non-utf-8 locale generated.
`vouch install-mcp <host>` resolved adapters/ relative to the repo root, which only exists in source checkouts. every pip/pipx install — including the published 1.1.0 wheel — fails with "unknown adapter 'claude-code' (available: (none))", so the readme's documented path to session auto-capture is broken for installed copies. force-include adapters/ into the wheel at vouch/adapters/ and fall back to that packaged copy when the repo-root directory is absent. checkouts and editable installs keep preferring the repo copy so dev edits win over a stale packaged snapshot. the regression test builds a wheel with the real backend (hatchling, now a dev dependency) and asserts the claude-code manifest is inside; it fails against the previous pyproject wheel config.
fix: pep 668 installer, non-utf-8 stdio, adapters missing from wheel
pr #367 force-included adapters/ into the wheel but the resolver hunk never made the branch: ADAPTERS_DIR still walked three parents up from the module — the repo root in a checkout, but <prefix>/lib/pythonX.Y/ in an installed wheel. installed copies therefore *contained* the templates yet still failed install-mcp with "(available: (none))". prefer the repo-root directory when it exists (checkouts, editable installs) and fall back to the packaged vouch/adapters/ otherwise. the wheel-contents regression test could not catch this — a wheel can carry the files while the resolver misses them — so a second test now unpacks the built wheel, imports that copy with no repo checkout in sight, and asserts available_adapters() finds claude-code.
click renders --help and --version during argument parsing, before any group callback runs — and the group docstring's em dash already crashes a latin-1 stdout. so the callback-scoped _force_utf8_stdio() from #367 left the very first command a fresh user is likely to type (`vouch --help`) raising UnicodeEncodeError. run it at module import instead; it is idempotent and a no-op on utf-8 streams. also widen capture.load_config's except: reading config.yaml with pinned utf-8 can now raise UnicodeDecodeError on latin-1 bytes (e.g. a hand-edited config on exactly the hosts this fix targets), which escaped the (OSError, YAMLError) tuple and broke the documented fall-back-to-defaults contract. the stdio regression test is parametrized over `status` and `--help`; the help case fails against the callback-scoped variant.
three hardening fixes for the pep 668 fallback from #367: - probe ~/.local/bin *before* deciding pipx is missing: fresh non-login shells often lack it on PATH, so an installed pipx looked absent and a needless private venv shadowed it. the symlink into ~/.local/bin now also refuses to overwrite an existing entry. - recreate the private venv from scratch on re-runs: brew pythons ship read-only activate scripts, so `python -m venv` over a previous run's env dies with EACCES. - stop announcing every pip failure as "refused (PEP 668)" and stop discarding installer output: attempts log to $TMPDIR and the final error prints the last lines, so a missing python3-venv or a network outage is diagnosable from the terminal.
fix: adapter resolution in wheels, eager-help crash, installer hardening (#367 follow-up)
roll [Unreleased] into a dated 1.2.0 section: the compile ingest pass, company-brain template + slash commands, digest, inbox, notify, source fetch, page filters, protected page kinds — plus the fresh-install fixes (pep 668 installer fallback, utf-8 stdio, adapters shipped in the wheel). version bumped in lockstep across pyproject.toml, openclaw.plugin.json and package.json (enforced by tests/test_openclaw_plugin_manifest.py). minor bump, not patch: the section ships features, not just fixes.
chore(release): prepare 1.2.0
|
Warning Review limit reached
Next review available in: 23 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. 📝 WalkthroughWalkthroughThis PR bumps package versions to 1.2.0, reworks install.sh's pipx bootstrapping to fall back to a private venv on PEP 668 hosts, forces UTF-8 stdio/file encoding across CLI and config modules, packages adapter templates inside the wheel, and adds corresponding tests and changelog entries. ChangesInstaller, UTF-8, and packaging fixes
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@install.sh`:
- Around line 165-167: The pipx install check in install.sh is too broad because
it returns for any pipx on PATH, including the fallback shim created by the
installer. Update the has_cmd pipx / pipx --version logic so only a valid,
working pipx is treated as already installed, and ensure the fallback symlink
path falls through to the private venv recreation flow. Keep the behavior
aligned with the install_pipx fallback/shim setup so reruns recreate the private
venv while preserving a user-provided ~/.local/bin/pipx.
- Around line 170-171: The pipx install log path is predictable in install.sh,
which makes the redirect vulnerable to symlink or clobber issues. Update the
pipx logging setup around the "$py" -m pip install --user --upgrade pipx call to
create pipx_log with mktemp instead of a fixed /tmp/vouch-install-pipx.log path,
and keep the rest of the install flow using that generated temporary filename.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 9d7d0168-5606-4233-8ca1-168aad96810c
📒 Files selected for processing (12)
CHANGELOG.mdinstall.shopenclaw.plugin.jsonpackage.jsonpyproject.tomlsrc/vouch/capture.pysrc/vouch/cli.pysrc/vouch/install_adapter.pysrc/vouch/migrations/rewriter.pysrc/vouch/themes.pytests/test_cli.pytests/test_install_adapter.py
two #370 review findings: - a leftover ~/.local/bin/pipx shim whose private venv died (e.g. a brew python upgrade) passed the has_cmd probe, so re-runs accepted the corpse as installed and never reached the recreation path. require a working `pipx --version` before returning early; verified end-to-end by breaking the venv and re-running. - the install log used a predictable /tmp path, which a pre-created symlink could redirect over a user-writable file. mktemp instead.
fix(install): self-heal a broken fallback pipx, mktemp for logs (#370 review)
promotes test to main for the 1.2.0 release. carries three PRs, all green on test's CI:
#367 — fresh-install fixes: pep 668 installer fallback, utf-8 stdio for non-utf-8 locales, adapter templates force-included into the wheel.
#368 — adversarial-review follow-ups to #367: the wheel's adapters are now actually resolved by installed copies (the resolver hunk had not made #367; a new regression test imports the built wheel's own package copy and asserts available_adapters() works), the utf-8 stdio reconfigure moved to module import so click's eager --help can't crash first, capture.load_config tolerates UnicodeDecodeError per its fall-back contract, and the installer became idempotent and honest about failures.
#369 — release prep: [Unreleased] rolled into a dated [1.2.0] section (compile, company-brain, digest, inbox, notify, source fetch, page filters, protected page kinds, plus the fixes above); version bumped in lockstep across pyproject.toml, openclaw.plugin.json and package.json.
after merge: tag v1.2.0 on main — release.yml publishes vouch-kb to pypi via trusted publishing, pushes ghcr images, and creates the github release with the changelog section as body.
Summary by CodeRabbit
New Features
Bug Fixes