Skip to content

fix(harness): split plugin root from consumer project root in all scripts (closes #63) - #66

Merged
robercano-ghbot merged 1 commit into
mainfrom
feat/issue-63-plugin-root-derivation
Jul 7, 2026
Merged

fix(harness): split plugin root from consumer project root in all scripts (closes #63)#66
robercano-ghbot merged 1 commit into
mainfrom
feat/issue-63-plugin-root-derivation

Conversation

@robercano-ghbot

Copy link
Copy Markdown
Collaborator

Closes #63.

Problem

Every script derived one root via ../.. from BASH_SOURCE, conflating two different roots. The plugin install cache strips the .claude/ prefix, so from the cache ../.. escapes the plugin and every sibling call ($root/.claude/scripts/bot-gh.sh) and project-asset path broke — pr-loop ticks only worked in repos still tracking legacy script copies.

Fix — one shared implementation

New scripts/resolve-roots.sh, sourced by all 10 scripts:

  • script_dir — the script's own dir, where siblings live in BOTH layouts (repo .claude/scripts/ and cache scripts/). All cross-script calls now use it.
  • root — consumer project root: repo-tracked layout (<x>/.claude/scripts<x>) wins so worktree gate runs keep anchoring to the worktree, else CLAUDE_PROJECT_DIR, else git toplevel of cwd, else cwd. Never fails (log-event's never-block contract).

Extras:

  • cockpit.sh: agents ship with the plugin → routing panel falls back to the plugin-layout agents/ dir; also replaced 2 literal NUL bytes (JS Map-key separator) with \u0000 so the file is text again (grep treated it as binary).
  • smoke-fanout.sh stages resolve-roots.sh beside gate.sh — the smoke caught the missing sibling on the very first run.

Testing

  • Self gates green incl. the fan-out smoke.
  • Full cache-layout repro from the issue: fake cache (scripts/ + agents/, no .claude/) + fixture consumer repo:
    • notify-poll.sh from cache reaches bot-gh.sh (fails on missing token, not No such file)
    • gate.sh from cache runs the consumer's gates with cwd=/ via CLAUDE_PROJECT_DIR, and via git-toplevel fallback with the var unset
    • cockpit.sh renders from cache with plugin agents; log-event.sh rc=0 writing consumer state
  • cockpit.test.sh + log-event.test.sh pass.

🤖 Generated with Claude Code

…ipts (closes #63)

Scripts derived one root via '../..' from BASH_SOURCE, which conflates two
different roots and breaks every script when run from the plugin install
cache (the cache strips the .claude/ prefix, so ../.. escapes the plugin).

New shared resolve-roots.sh (sourced by all 10 scripts — one implementation):
- script_dir: this script's own dir — where SIBLINGS live in both layouts;
  all cross-script calls (bot-gh.sh etc.) now use it.
- root: consumer project root — repo-tracked layout (<x>/.claude/scripts)
  wins so worktree gate runs keep anchoring to the worktree, else
  CLAUDE_PROJECT_DIR, else git toplevel of cwd, else cwd. Never fails
  (log-event.sh's never-block contract).

cockpit.sh: agents ship with the plugin, so the routing panel falls back to
the plugin-layout agents/ dir when the project has no .claude/agents; also
replaced 2 literal NUL bytes (Map-key separator in embedded JS) with \u0000
so the file is text again and grep-able.

smoke-fanout.sh stages resolve-roots.sh beside gate.sh (the smoke caught the
missing-sibling case immediately).

Verified: self gates green incl. fan-out smoke; cache-layout repro from the
issue passes end-to-end (notify-poll reaches bot-gh.sh; gate.sh runs the
consumer's gates from cwd=/ via CLAUDE_PROJECT_DIR and via git fallback;
cockpit renders with plugin agents; log-event rc=0 writing consumer state).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01NTZEsfFT4mrZpv8CY67Frd
@robercano-ghbot
robercano-ghbot merged commit 75ebb6c into main Jul 7, 2026
9 checks passed
@robercano-ghbot
robercano-ghbot deleted the feat/issue-63-plugin-root-derivation branch July 7, 2026 13:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

scripts break when run from the plugin install cache (CLAUDE_PLUGIN_ROOT): root derived as ../.. conflates plugin root with consumer project root

2 participants