diff --git a/.claude/rules/tea-cli.md b/.claude/rules/tea-cli.md index 7813c40cb..ab9e74b21 100644 --- a/.claude/rules/tea-cli.md +++ b/.claude/rules/tea-cli.md @@ -28,6 +28,7 @@ tea issue list --login schweitz --repo jpmschweitzer/settled-reach --state open - **Use `--output simple`** for machine-readable output (no table borders) - **For comments, use `tooling/tea-comment @/tmp/file.md`** for long comments (write to file first, then pass `@filepath`). Short inline strings also work: `tooling/tea-comment "body"`. The `@filepath` form avoids `$()` subshells which break permission matching. - **`tea pr reject` does not work on your own PRs** — use `tea comment` instead +- **Run `tea` from the main checkout, never a linked worktree** — its go-git can't read a worktree's `.git` *file* and errors with "local/remote repository required". `tea pr create`/`close`/`comment` all take explicit `--login`/`--head`/`--base`, so cwd only needs to be the main repo, not the branch's worktree. - **Never delete protected branches:** `main`, `maintenance`, `server`, `client`, `copy`, `audio`, `visual`, `ci` are protected on Gitea. Do not use `tea pr clean`, `git push --delete`, or `git branch -D` on these branches. ## Pull requests diff --git a/.claude/skills/whats-next/SKILL.md b/.claude/skills/whats-next/SKILL.md index 0ccbcd330..47f2b8ecf 100644 --- a/.claude/skills/whats-next/SKILL.md +++ b/.claude/skills/whats-next/SKILL.md @@ -192,21 +192,31 @@ git checkout -b ### 3c. Create worktree (optional) -If the user wants to work in a separate worktree: - -Worktrees live **inside the repo** under the gitignored `.worktrees/` directory -(see `.gitignore` — "created under the repo root"). Never place them in the repo's -parent directory: paths outside the repo are outside the permission sandbox and -break agent file access. +If the user wants to work in a separate worktree, use the helper — it creates the +worktree under the gitignored `.worktrees/` dir (inside the repo; never the parent +dir — paths outside the repo are outside the permission sandbox and break agent +file access), symlinks the `.venv` (so `make test-tooling`/`regen-db` and python +tooling resolve `.venv/bin/python`), and prints the in-worktree reminders: ```bash -REPO_ROOT=$(git rev-parse --show-toplevel) -WORKTREE_DIR="$REPO_ROOT/.worktrees/" -git worktree add "$WORKTREE_DIR" +tooling/worktree-setup # run from the main checkout ``` Report the worktree path so the user can open a terminal there. +**Working inside the worktree — two gotchas the helper reminds you of:** +- **pql needs `--vault ""`.** pql finds its vault by walking up + for a `.git` *directory*; a worktree's `.git` is a *file*, so a bare `pql` from a + worktree resolves to the **main** checkout (upstream bug, FR-4). The `post-checkout` + hook already passes `--vault` so the worktree's `pql.db` is populated on creation, + but any `pql` *you or an agent* run inside the worktree must pass it too. (Planning + ops like `pql ticket status` are usually fine run from **main** instead.) +- **`tea` runs from the main checkout**, not the worktree — its go-git can't read a + linked worktree's `.git` file. +- **Content agents may spawn read-only** (Read/Grep/SendMessage, no Write) — if one + composes a file it can't write, it SendMessages the content to you (the lead) to + place. Verify what you place (don't take "cross-checked" on trust). + **Lifecycle:** a worktree created here is torn down at the *end* of the work, not here. `/pr-review` §7a removes it (and deletes the merged branch) by default once the PR merges. If you activate a batch and the work never ships, the worktree is diff --git a/tooling/worktree-setup b/tooling/worktree-setup new file mode 100755 index 000000000..9e73686f5 --- /dev/null +++ b/tooling/worktree-setup @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +# worktree-setup — create a git worktree that's immediately usable. +# +# Collapses the /whats-next §3c ritual into one command. A bare +# `git worktree add` leaves two things broken that bit the Layer-5 batch: +# 1. no `.venv` in the worktree, so `make test-tooling` / `make regen-db` / +# any python tooling can't find `.venv/bin/python`; +# 2. (fixed separately in .config/hooks/post-checkout) pql resolving the +# worktree's `.git` *file* to the MAIN checkout — the post-checkout hook +# now passes `--vault`, so this script relies on it for the pql rebuild. +# +# This script adds the worktree under the repo's gitignored `.worktrees/` +# (never the parent dir — outside the permission sandbox), symlinks the venv, +# and prints the worktree path + the in-worktree reminders. +# +# Usage: tooling/worktree-setup [] +# (run from the MAIN checkout, not a linked worktree) +set -euo pipefail + +branch="${1:?usage: tooling/worktree-setup []}" +start="${2:-HEAD}" + +repo_root="$(git rev-parse --show-toplevel)" +if [ -f "$repo_root/.git" ]; then + echo "worktree-setup: run this from the MAIN checkout, not a worktree" >&2 + exit 1 +fi + +wt_dir="$repo_root/.worktrees/$branch" +if [ -e "$wt_dir" ]; then + echo "worktree-setup: $wt_dir already exists — reuse it or 'git worktree remove' it first" >&2 + exit 1 +fi + +# The post-checkout hook (.config/hooks/post-checkout) fires here and rebuilds +# the new worktree's pql.db via `pql --vault `. +git worktree add "$wt_dir" -b "$branch" "$start" + +# Symlink the venv — worktrees don't copy it and a fresh per-worktree venv is +# wasteful (the main one is identical). Makes `.venv/bin/python` resolve so the +# Makefile's VENV_PY and every python tool work inside the worktree. +if [ -d "$repo_root/.venv" ] && [ ! -e "$wt_dir/.venv" ]; then + ln -s "$repo_root/.venv" "$wt_dir/.venv" + echo " linked .venv -> $repo_root/.venv" +fi + +echo "worktree ready: $wt_dir" +echo " reminders: pql in this worktree needs --vault \"$wt_dir\" (FR-4);" +echo " tea commands run from the main checkout (go-git can't read a linked worktree)."