Start cleanly when bench is the project itself
Three layout defects broke ./start.sh in the self-hosted repo, one of which (missing local/state/) broke every fresh vendored install too: - install.py resolved the project as TM.parent, a hardcoded vendored- layout assumption. It now asks git for the toplevel from the manager's directory (same resolution as config._repo_root), falling back to the parent when git is unavailable — vendored installs still find the host repo, self-hosted bench finds itself instead of its parent. - adapters/claude/wire hardcoded ".task-manager/" into the emit hook command and plansDirectory. Both are now derived from the manager's path relative to the project root, so vendored installs keep the .task-manager/ prefix and self-hosted bench gets prefix-free paths. _is_ours also recognises the emit.py suffix, so settings wired with the old literal path count as stale and are repaired idempotently. - board.py and state.py created the sessions/agent dirs without parents=True; local/state/ is gitignored and ships empty, so a virgin checkout died with FileNotFoundError before serving. Boot now creates the whole chain, wiring or no wiring. tests/test_self_hosting.py (stdlib unittest) covers both layouts' wiring, stale-path repair, idempotent re-runs, refusal without .claude/, root resolution with and without git, and an integration boot of board.py from a scratch checkout with no local/state/. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+21
-1
@@ -19,11 +19,31 @@ import sys
|
||||
from pathlib import Path
|
||||
|
||||
TM = Path(__file__).resolve().parent
|
||||
PROJECT = TM.parent
|
||||
LOCAL = TM / "manager" / "local"
|
||||
CORE = TM / "manager" / "core"
|
||||
|
||||
|
||||
def _project_root() -> Path:
|
||||
"""The host project's root: the git toplevel seen from the manager's
|
||||
directory (same resolution as config._repo_root). Vendored installs
|
||||
drop .task-manager/.git at clone time, so this finds the host repo;
|
||||
when the manager IS the repo (self-hosted), it finds that repo itself.
|
||||
No git → fall back to the vendored-layout assumption, the parent."""
|
||||
try:
|
||||
out = subprocess.check_output(
|
||||
["git", "-C", str(TM), "rev-parse", "--show-toplevel"],
|
||||
text=True, stderr=subprocess.DEVNULL,
|
||||
).strip()
|
||||
if out:
|
||||
return Path(out)
|
||||
except (subprocess.CalledProcessError, OSError):
|
||||
pass
|
||||
return TM.parent
|
||||
|
||||
|
||||
PROJECT = _project_root()
|
||||
|
||||
|
||||
def adapter_name() -> str:
|
||||
if os.environ.get("BOARD_AGENT_ADAPTER"):
|
||||
return os.environ["BOARD_AGENT_ADAPTER"]
|
||||
|
||||
Reference in New Issue
Block a user