Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,9 @@ observable.

Install first from the [Install And Bootstrap](docs/install.md) matrix: pipx for
laptops, uv tool installs for hosted agents or CI boxes, and an editable venv
for Code Mower contributors. All paths require Python 3.12 or newer.
for Code Mower contributors. All paths require Python 3.12 or newer. For
upgrades, record `command -v code-mower` and `code-mower --version` before and
after reinstalling, especially when switching between pipx and uv.

| Path | Use When | Route | Guide |
| --- | --- | --- | --- |
Expand Down
79 changes: 79 additions & 0 deletions docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,36 @@ agent, then verify the installed command before touching a repository.
| Hosted agent, CI box, or minimal Linux VM | `uv tool install` | The machine already uses uv, lacks pipx, or should avoid changing shell startup files. |
| Code Mower contributor checkout | editable venv | You are changing Code Mower itself and need tests against this checkout. |

## Cold Install Vs Upgrade

A cold install means this machine does not already have the `code-mower`
command on `PATH`. Pick one install path from the matrix, install the pinned
package, then verify both the command path and version:

```bash
command -v code-mower
code-mower --version
```

An upgrade means `code-mower` already exists. Before changing it, record the
current command path and version, then choose whether this machine should keep
using the same installer or switch installers:

```bash
command -v code-mower
code-mower --version
```

For an existing repository with older generated files, inspect setup drift
before copying new generated output into the repo:

```bash
code-mower migration setup-drift --repo-path . --json
```

The drift report is read-only and metadata-only. It classifies generated setup
paths without including file contents or diffs.

## Laptop Or Workstation

Install with pipx and an explicit Python 3.12+ interpreter:
Expand All @@ -35,6 +65,27 @@ To follow the newest prerelease instead of the pinned friendly-user beta:
pipx install --python "$CODE_MOWER_PYTHON" --pip-args="--pre" code-mower
```

To replace an existing pipx install with an exact beta, use `--force` so the
old venv cannot keep serving the previous package:

```bash
PIP_NO_CACHE_DIR=1 pipx install --force --python "$CODE_MOWER_PYTHON" code-mower==0.8.0b1
code-mower --version
```

For sandboxed agents that need pipx but should not write to the normal user
tool directories, set pipx directories explicitly before installing:

```bash
export CODE_MOWER_AGENT_TOOLS="${RUNNER_TEMP:-$HOME/.cache}/code-mower-tools"
export PIPX_HOME="$CODE_MOWER_AGENT_TOOLS/pipx"
export PIPX_BIN_DIR="$CODE_MOWER_AGENT_TOOLS/bin"
export PIPX_LOG_DIR="$CODE_MOWER_AGENT_TOOLS/logs"
mkdir -p "$PIPX_HOME" "$PIPX_BIN_DIR" "$PIPX_LOG_DIR"
PIP_NO_CACHE_DIR=1 pipx install --force --python "$CODE_MOWER_PYTHON" code-mower==0.8.0b1
"$PIPX_BIN_DIR/code-mower" --version
```

## Hosted Agent, CI Box, Or Minimal Linux VM

Use uv when the environment does not have pipx or should stay isolated from the
Expand All @@ -49,6 +100,34 @@ code-mower --version
If the uv tool directory is not on `PATH`, use uv's printed path hint or run the
installed command directly from the uv tool bin directory for that session.

To replace an existing uv tool install with an exact beta:

```bash
uv tool install --python 3.12 --reinstall --refresh-package code-mower code-mower==0.8.0b1
code-mower --version
```

## Switching Between pipx And uv

Avoid leaving two different `code-mower` commands competing on `PATH`. If this
machine should switch from pipx to uv, first record the current path/version,
then uninstall or stop using the old command:

```bash
command -v code-mower
code-mower --version
pipx uninstall code-mower
uv python install 3.12
uv tool install --python 3.12 --reinstall --refresh-package code-mower code-mower==0.8.0b1
hash -r
command -v code-mower
code-mower --version
```

If the old pipx command must stay for another agent, call the uv-installed
binary by its absolute path or adjust only that agent's `PATH`. Do not change a
shared workstation install while another builder owns an active PR branch.

## Release Rehearsal Installs

When validating a newly published beta, bypass installer caches before deciding
Expand Down
18 changes: 17 additions & 1 deletion docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,17 @@ For hosted agents or CI boxes without pipx:
```bash
uv python install 3.12
uv tool install --python 3.12 code-mower==0.8.0b1
code-mower --version
```

For a Code Mower source checkout, use `scripts/dev-python` and the editable
venv path documented in [Install And Bootstrap](install.md#contributor-checkout).

For upgrades, do not assume the command on `PATH` changed. Run
`command -v code-mower` and `code-mower --version` before and after reinstall,
and follow [Cold Install Vs Upgrade](install.md#cold-install-vs-upgrade) when
moving between pipx and uv.

If `code-mower` is not on your path:

```bash
Expand Down Expand Up @@ -79,7 +85,17 @@ Verify Codex:

```bash
codex --version
codex "Reply with exactly: ok"
codex login status
codex exec --skip-git-repo-check --sandbox read-only "Reply with exactly: ok"
```

For non-interactive runner or hosted-agent auth, load the API key from a secret
store and pipe it into Codex without printing it:

```bash
printf '%s\n' "$OPENAI_API_KEY" | codex login --with-api-key
codex login status
codex exec --skip-git-repo-check --sandbox read-only "Reply with exactly: ok"
```

Verify Claude:
Expand Down
49 changes: 49 additions & 0 deletions docs/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,46 @@ scripts/dev-python -m unittest discover -s tests

The wrapper resolves Python 3.12+ and refuses old system Python shims.

## Installed Version Or Command Path Looks Wrong

After an upgrade, first check which installer is actually winning on `PATH`:

```bash
command -v code-mower
code-mower --version
```

If pipx should own the command, reinstall the exact beta with cache bypass:

```bash
export CODE_MOWER_PYTHON="$(command -v python3.12)"
PIP_NO_CACHE_DIR=1 pipx install --force --python "$CODE_MOWER_PYTHON" code-mower==0.8.0b1
hash -r
code-mower --version
```

If uv should own the command, avoid leaving an older pipx command earlier on
`PATH`. Either uninstall the pipx copy or call the uv binary by its absolute
path:

```bash
pipx uninstall code-mower
uv tool install --python 3.12 --reinstall --refresh-package code-mower code-mower==0.8.0b1
hash -r
command -v code-mower
code-mower --version
```

For sandboxed agents using pipx, keep tool files out of the product checkout
unless that directory is intentionally ignored:

```bash
export CODE_MOWER_AGENT_TOOLS="${RUNNER_TEMP:-$HOME/.cache}/code-mower-tools"
export PIPX_HOME="$CODE_MOWER_AGENT_TOOLS/pipx"
export PIPX_BIN_DIR="$CODE_MOWER_AGENT_TOOLS/bin"
export PIPX_LOG_DIR="$CODE_MOWER_AGENT_TOOLS/logs"
```

## GitHub Auth Or Private Repo Checks Fail

Verify the GitHub CLI independently:
Expand Down Expand Up @@ -105,6 +145,15 @@ output, treat it as audit infrastructure, not a code-review BLOCKED verdict.
Retry once on the same head; if it repeats, keep the lane informational or
record an owner decision before relying on it.

## Board URL Does Not Open From Another Machine

`code-mower board serve --repo OWNER/REPO` binds to loopback by default. The
printed localhost URL is local to that laptop, runner, VM, or hosted-agent
container. Open it from the same environment, or create your own tunnel when
you intentionally want to view it elsewhere. The Board remains read-only and
does not upload data unless you separately run a cloud command such as
`code-mower cloud board-snapshot --yes`.

## Cloud Upload Says The Token Is Missing After Restart

`code-mower cloud setup --token-stdin` writes a private token profile under
Expand Down
19 changes: 18 additions & 1 deletion docs/try-in-10-minutes.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,32 @@ private repository names.

Code Mower requires Python 3.12 or newer. See
[Install And Bootstrap](install.md) for pipx, uv, and contributor checkout
paths. The laptop path is:
paths, plus upgrade and pipx-to-uv migration details.

Use this install matrix:

| Environment | Command shape |
| --- | --- |
| Laptop/workstation | `pipx install --python "$CODE_MOWER_PYTHON" code-mower==0.8.0b1` |
| Hosted agent, CI box, or minimal Linux VM | `uv tool install --python 3.12 code-mower==0.8.0b1` |
| Code Mower contributor checkout | `scripts/dev-python -m venv .venv` then `.venv/bin/python -m pip install -e ".[test]"` |

For a cold laptop install:

```bash
python3.12 --version
export CODE_MOWER_PYTHON="$(command -v python3.12)"
pipx install --python "$CODE_MOWER_PYTHON" code-mower==0.8.0b1
command -v code-mower
code-mower --version
```

For an existing install, first run `command -v code-mower` and
`code-mower --version`, then follow
[Cold Install Vs Upgrade](install.md#cold-install-vs-upgrade). If you switch
from pipx to uv, make sure the command on `PATH` is the one you meant to use
before running `init`.

`0.8.0b1` is a beta release. To follow the newest beta line instead of
pinning this exact build:

Expand Down
25 changes: 25 additions & 0 deletions tests/test_release_hygiene.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,31 @@ def test_codex_smoke_docs_use_supported_flags(self) -> None:
self.assertNotIn("--ask-for-approval", text, msg=str(path))
self.assertIn("codex login --with-api-key", text, msg=str(path))

def test_install_and_upgrade_docs_cover_agent_paths(self) -> None:
readme = (ROOT / "README.md").read_text(encoding="utf-8")
install = (ROOT / "docs/install.md").read_text(encoding="utf-8")
quickstart = (ROOT / "docs/quickstart.md").read_text(encoding="utf-8")
try_in_10 = (ROOT / "docs/try-in-10-minutes.md").read_text(encoding="utf-8")
troubleshooting = (ROOT / "docs/troubleshooting.md").read_text(encoding="utf-8")

self.assertIn("Cold Install Vs Upgrade", install)
self.assertIn("Switching Between pipx And uv", install)
self.assertIn("uv tool install --python 3.12 --reinstall --refresh-package", install)
self.assertIn("pipx uninstall code-mower", install)
for env_name in ("PIPX_HOME", "PIPX_BIN_DIR", "PIPX_LOG_DIR"):
self.assertIn(env_name, install)
self.assertIn(env_name, troubleshooting)
self.assertIn("| Hosted agent, CI box, or minimal Linux VM |", try_in_10)
self.assertIn("command -v code-mower", readme)
self.assertIn("command -v code-mower", quickstart)
self.assertIn("codex login --with-api-key", quickstart)
self.assertIn("codex exec --skip-git-repo-check --sandbox read-only", quickstart)
self.assertIn("Board URL Does Not Open From Another Machine", troubleshooting)
self.assertIn(
"local to that laptop, runner, VM, or hosted-agent container",
" ".join(troubleshooting.split()),
)

def test_ruff_static_rule_stage_is_intentional(self) -> None:
pyproject = tomllib.loads((ROOT / "pyproject.toml").read_text(encoding="utf-8"))

Expand Down
Loading