5d79df9ab058b6e532ee9fd1817e47f098d52081
6 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
3d354465f0 |
fix(install): name the profile the user's shell actually reads
prd-number-check / require-numbered-prds (pull_request) Successful in 11s
tracker-policy-pr / check-pr (pull_request) Successful in 9s
test / image-input-builds (pull_request) Successful in 38s
test / unit (pull_request) Successful in 43s
test / integration-docker (pull_request) Successful in 59s
test / coverage (pull_request) Successful in 16s
The PATH hint hardcoded ~/.zprofile, which is right for macOS's zsh and wrong for the Linux users this installer also serves. Pick from $SHELL instead. ~/.profile is the default for non-zsh rather than ~/.bash_profile, because creating the latter would shadow an existing ~/.profile. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WEfZZhakx13bxTfXcZCoS5 |
||
|
|
90d6104e17 |
fix(install): install into a private venv when pipx is absent
prd-number-check / require-numbered-prds (pull_request) Successful in 5s
test / image-input-builds (pull_request) Successful in 38s
test / unit (pull_request) Successful in 44s
tracker-policy-pr / check-pr (pull_request) Successful in 4s
lint / lint (push) Successful in 53s
test / integration-docker (pull_request) Successful in 58s
test / coverage (pull_request) Successful in 18s
The harness's second run hit the wall the first one predicted: a fresh account has no pipx, so install.sh fell to `pip install --user`, and every Python a Mac offers — Homebrew and python.org alike — is externally managed, so PEP 668 blocked it. That fallback was never a fallback on macOS; it was a dead end that printed instructions. Replace it with a venv at ~/.bot-bottle/venv (BOT_BOTTLE_VENV to move it), with the console script symlinked into ~/.local/bin. PEP 668 does not apply inside a venv, and venv is stdlib, so unlike pipx there is nothing to bootstrap first. pipx stays the preferred path when present, so anyone already managing their Python apps that way is unaffected — and the post-install PATH check now asks pipx for PIPX_BIN_DIR instead of assuming ~/.local/bin. Keeping the venv under ~/.bot-bottle rather than ~/.local/share means the whole footprint stays in one directory, which is what lets the throwaway-account teardown remain a complete reset. This removes the PEP 668 pre-flight and the sysconfig user-scheme lookup, both of which existed only to serve the --user path. Their tests go with them: * `detects_externally_managed_python` asserted the check that is now moot; replaced by one asserting pipx is still preferred when present. * `checks_pip_usable_before_fallback` pinned a pip probe that no longer runs; replaced by one asserting the venv's own pip does the install, since using the base interpreter's would install outside the venv. * `resolves_user_scripts_dir_not_hardcoded` and `macos_user_scheme_is_not_dot_local_bin` guarded the ~/Library/Python scripts-dir lookup. Nothing installs there now. The surviving "don't hardcode" concern is pipx's bin dir, which has its own test. Five tests are added for the new path: the venv fallback exists, no --user path survives, the venv is under the config dir, venv creation failure names python3-venv (Debian ships it separately), and the entry point is exposed outside the venv. Verified end to end in a sandbox HOME with a fresh-account PATH and no pipx: venv built, package installed, symlink created, `doctor` reached and green (python 3.14.5, macos-container ready), exit 0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WEfZZhakx13bxTfXcZCoS5 |
||
|
|
c62aa7b805 |
fix(install): find a usable python instead of dead-ending on PATH's
prd-number-check / require-numbered-prds (pull_request) Successful in 10s
tracker-policy-pr / check-pr (pull_request) Successful in 13s
test / image-input-builds (pull_request) Successful in 43s
test / unit (pull_request) Successful in 51s
test / integration-docker (pull_request) Successful in 59s
test / coverage (pull_request) Successful in 15s
lint / lint (push) Failing after 14m25s
The macOS install harness caught this on its first real run: a throwaway account gets `bot-bottle install: error: python3 3.11 or newer is required` and stops. A fresh account's PATH is just /etc/paths, which excludes /opt/homebrew/bin, so `python3` resolves to the Command Line Tools stub — still 3.9.6 on macOS 26. Homebrew's shellenv line lives in the *installing* user's ~/.zprofile and is inherited by nobody. The documented `curl … | sh` path therefore dead-ends for anyone whose profile isn't already set up, which is every new user, launchd job, and CI runner. So look past PATH before giving up: try `python3`, then python3.11-3.14, then /opt/homebrew/bin, /usr/local/bin, ~/.local/bin, and python.org framework builds, and say which one was picked when it isn't the obvious one. On this host that turns the failure into a successful install. The chosen interpreter is now threaded through everything downstream — the pip probe, the PEP 668 check, the pip --user fallback, and the user-scripts-dir lookup — which were all still hardcoding `python3` and would otherwise have run against the 3.9 stub we just rejected. `pipx install` gains `--python`, since pipx otherwise builds the venv with whichever interpreter pipx itself was installed with, not the one that passed the version check. When nothing usable is found the error is now actionable: what was found and why it's insufficient, where else it looked, a platform-appropriate install command, and BOT_BOTTLE_PYTHON to point at an interpreter directly. An explicit BOT_BOTTLE_PYTHON that is too old or unusable is an error rather than a silent fallback to a different interpreter than the caller asked for. Three existing tests asserted on incidental literals rather than the behaviour they describe, and are narrowed to their actual intent: * `never_uses_sudo` matched the word anywhere, including the new "sudo apt install python3.12" remediation *advice*. It now strips string literals and comments first, so it still catches sudo as a bare command, in a pipeline, and in a command substitution — verified by mutation — while allowing the script to print the word. * `checks_pip_usable_before_fallback` pinned the literal `python3 -m pip`. * `resolves_user_scripts_dir_not_hardcoded` banned ".local/bin" script-wide; it's now scoped to the USER_SCRIPTS assignment it exists to guard, since ~/.local/bin is a legitimate place to *find an interpreter*. README grows the install command and a Requirements section it never had, leading with the Python floor and why a working `python3` in your own shell says nothing about what a fresh account sees. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WEfZZhakx13bxTfXcZCoS5 |
||
|
|
82669b22d5 |
fix: doctor probes backend readiness; install.sh resolves user-scripts dir
test / integration-docker (push) Successful in 20s
prd-number / assign-numbers (push) Failing after 24s
test / unit (push) Successful in 57s
lint / lint (push) Successful in 1m1s
Update Quality Badges / update-badges (push) Failing after 54s
test / integration-firecracker (push) Successful in 5m7s
test / coverage (push) Successful in 27s
test / publish-infra (push) Successful in 2m34s
Addresses the third review round on PR #481. - `bot-bottle doctor` now checks `is_backend_ready()` (a full backend status() probe: daemon reachable, network pool present, KVM usable) instead of the cheap PATH-only `is_backend_available()`. A host with a stopped Docker daemon or half-configured Firecracker no longer reports `ok: backend` / exit 0 when `start` can't actually work; each not-ready backend prints its own diagnostics, and doctor passes only if at least one backend is ready. - `install.sh` resolves the pip `--user` scripts directory from the interpreter (`sysconfig.get_path("scripts", get_preferred_scheme("user"))`) instead of hardcoding `~/.local/bin`, which is wrong on a python.org macOS interpreter (`~/Library/Python/<X.Y>/bin`). The PATH guidance now prints the actual directory. Tests: doctor tests mock `is_backend_ready` (the readiness contract) and cover the not-ready → fail path; a new install-script test drives the macOS `osx_framework_user` scheme and asserts it resolves a non-~/.local/bin directory. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
1a4b390e8a |
fix: make installed wheel self-contained + harden install.sh prereqs
Addresses the review on PR #481. Self-contained wheel (review point 1): the gateway/infra/orchestrator images build from a context that must hold bot_bottle/, pyproject.toml, and the root-level Dockerfiles. Modules previously located these by walking __file__ to the repo root, so an installed wheel (package in site-packages, no repo root) passed `doctor` but failed `start`. - Add bot_bottle/resources.py: build_root() returns the repo root in a checkout (unchanged) or a staged copy from the wheel's bundled _resources/ otherwise; dockerfile()/nix_netpool_module()/ netpool_script() derive from it. - setup.py bundles the root Dockerfiles, nix module, netpool script, and pyproject.toml into bot_bottle/_resources/ at build; MANIFEST.in ships them in the sdist. - Route every _REPO_ROOT/_REPO_DIR call site (docker/macos launch, macos infra, firecracker infra_vm/infra_artifact/setup, orchestrator lifecycle/gateway) through resources. Checkout behavior is unchanged. install.sh prerequisites (review point 2): check for git when installing a git+ spec, and — before the pip fallback — that pip is usable and the interpreter isn't externally managed (PEP 668), pointing at pipx. Tests: test_resources covers checkout + staged-wheel layouts; test_wheel_install builds the wheel, installs it into an isolated venv, and asserts `doctor` runs and build_root() yields a valid context. Running `start` end-to-end still needs a Docker/KVM host (CI). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
955cb3bcbd |
feat: add quick install script and packaging (#197)
Give bot-bottle a real distribution path so new users can install
without cloning the repo:
- pyproject.toml: full project metadata, a `bot-bottle` console-script
entry point (bot_bottle.cli:main), and package-data for the runtime
assets (Dockerfiles, egress entrypoint, netpool defaults, macos init).
Still zero runtime pip dependencies.
- install.sh: POSIX, sudo-free, idempotent bootstrapper — checks Python
>= 3.11, creates ~/.bot-bottle/{agents,bottles,contrib}, installs via
pipx (pip --user fallback), then runs `bot-bottle doctor`.
- `bot-bottle doctor`: new store-free subcommand reporting Python
version, backend availability (reuses is_backend_available rather than
hardcoding Docker), and config-dir presence. Exits non-zero when a hard
prerequisite is unmet.
- PRD prd-new-install-script and unit tests for doctor, the packaging
contract, and the install script.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|