Skip to content

fix(claude): register the binary by its symlink, not the build behind it - #36

Merged
jayhesselberth merged 1 commit into
mainfrom
worktree-install-registers-the-stable-path
Aug 29, 2026
Merged

fix(claude): register the binary by its symlink, not the build behind it#36
jayhesselberth merged 1 commit into
mainfrom
worktree-install-registers-the-stable-path

Conversation

@jayhesselberth

Copy link
Copy Markdown
Member

Why

sinteractive claude install after #30 + #29 registered the hooks, statusline and MCP server under the build's own file, ~/.local/bin/.sinteractive-<sha> (current_exe() resolves the symlink) — a name a later install prunes, which would have left every hook pointing at nothing. And because the identity/migration regexes did not recognise that spelling as this program, each run migrated the stable entries onto the versioned name and then appended the snippet's entries again: after one run, two copies of every hook. Seen on this user's settings.json today.

What

  • exe_command() registers the sinteractive symlink when one beside the binary resolves to it (stable_exe); a plain file keeps its own name.
  • .sinteractive-<hex> counts as this program wherever a command is examined — hook_identity, renamed_command, is_our_mcp_entry — so what the broken install wrote is migrated back onto the stable name.
  • dedupe_our_hooks: duplicate entries of ours within an event are folded into one; the user's own entries are never touched, however alike.
  • Alpine compute skill: one CARGO_TARGET_DIR per project/agent — two cargo runs from different nodes in one target dir clobber each other (seen today).

Tested

Unit tests for the symlink resolution (tempdir), the versioned spellings, dedupe, MCP repoint; cargo test -p sint -- install_claude:: and the install_claude integration tests passed in a private target dir before the shared cache was wiped mid-session by another job; CI is the full run.

🤖 Generated with Claude Code

https://claude.ai/code/session_01MuezDnJq5Qh34SoGGAgzZU

Since builds land at .sinteractive-<sha> behind a `sinteractive` symlink
(#30), current_exe() resolves to the build's own file, and `claude
install` (#29, absolute paths) wrote that name into the hooks, the
statusline and the MCP entry. That name is one a later install prunes
once no session can be running it, which would have left every hook
pointing at nothing. Worse, the identity and migration regexes did not
recognise the spelling as this program, so each run migrated the stable
entries onto the build's name and then appended the snippet's entries
again: two copies of every hook after one run.

The registered name is now the symlink when one beside the binary
resolves to it (a plain file keeps its own name), `.sinteractive-<hex>`
counts as this program wherever a command is examined — hooks and the
MCP entry — so what the broken install wrote is migrated back, and
duplicate entries of ours are folded into one. The user's own entries
are never touched, however alike.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MuezDnJq5Qh34SoGGAgzZU
@jayhesselberth
jayhesselberth merged commit e42819c into main Aug 29, 2026
3 checks passed
@jayhesselberth
jayhesselberth deleted the worktree-install-registers-the-stable-path branch August 29, 2026 19:45
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.

1 participant