Changelog
2026-04-26by Fatih
Session tracker and PR attribution hooks were never running
Both hooks existed but weren't declared in plugin.json, so every skill invocation went untracked and every PR shipped without agent attribution. Six related bugs fixed in the same pass.
fix
Fixed
- -`tonone-session-tracker.js` and `tonone-pr-attribution.js` never ran: both hooks existed but were not declared in
.claude-plugin/plugin.json. Every Skill invocation went untracked and every PR shipped without agent attribution since the hooks were added. - -`tonone-worktree-session.js` missing: tests expected this SessionStart hook, but it was never created. It now prunes stale git worktrees at session start and emits a ready status so Claude knows whether it's resuming an existing worktree or starting fresh on main.
- -`tonone-worktree-session.js` not registered: implemented but absent from the
SessionStartarray inplugin.json, making the prune and status features dead code. - -`tonone-git-gate.js` passed the wrong argument to `EnterWorktree`: the blocked-on-main recovery message passed the branch slug instead of the full worktree path.
- -`tonone-git-gate.js` TOCTOU: two separate
execSynccalls for--git-dirand--git-common-dircould race if git state changed between calls. Merged into a single atomic invocation. - -Array bounds bug: git output was split by newline without a length check, so a shorter-than-expected result would incorrectly treat main as a worktree.
- -`tonone-pr-attribution.js` silent failure: a falsy
.outputfield fell through to stringifying the whole object, silently failing to extract the GitHub PR URL on every PR. - -`bump-version.py` corrupted active worktrees: its glob recursed into
.claude/worktrees/, writing version changes into every active worktree. Now excludes it.