Skip to content

fix(install): refuse conflicting Hunk installs - #960

Merged
benvinegar merged 2 commits into
mainfrom
fix/install-conflicts
Aug 31, 2026
Merged

fix(install): refuse conflicting Hunk installs#960
benvinegar merged 2 commits into
mainfrom
fix/install-conflicts

Conversation

@benvinegar

Copy link
Copy Markdown
Member

Summary

  • refuse curl-installer upgrades when another Hunk binary is on PATH or under a known inactive nvm/mise install
  • report every competing path, version, likely owner, and PATH shadowing direction with removal guidance
  • add an explicit --force / HUNK_ALLOW_CONFLICTING_INSTALLS=1 opt-out and emphasize restarting every existing terminal pane
  • document the behavior and add regression coverage

Context

Multiple package-manager installs can leave old terminal panes resolving an older Hunk even after ~/.hunk/bin/hunk is upgraded. The installer previously discovered only the first foreign binary and silently continued whenever its version differed.

Fresh main already contains the quiescent authenticated daemon migration from #933. I verified that current clients no longer retain the PID-based incompatible-daemon replacement path: incompatible incumbents are not signalled, and unauthenticated callers cannot invoke session controls or induce a restart.

Validation

  • bun test scripts/install-sh.test.ts — 12 passed
  • bun test src/session/broker/brokerClient.test.ts src/session/broker/brokerServer.test.ts src/session/agent/commands.test.ts — 49 passed
  • bun run typecheck
  • sh -n install.sh
  • shellcheck -s sh install.sh
  • bunx oxfmt --check scripts/install-sh.test.ts website/src/content/docs/docs/start/install.md .changeset/quiet-install-conflicts.md
  • git diff --check

Tested on Linux; the installer regression harness stubs all published macOS/Linux platform pairs, but I did not run the installer on macOS.

This PR description was generated by Pi using GPT-5.6 Sol

@vercel

vercel Bot commented Aug 31, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hunk-web Ready Ready Preview Aug 31, 2026 7:46pm

Request Review

@greptile-apps

greptile-apps Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR makes the curl installer reject competing Hunk installations unless explicitly forced and adds detailed conflict diagnostics, documentation, and regression coverage.

  • Enumerates Hunk executables on PATH and in known inactive nvm/mise locations.
  • Reports version, likely package-manager owner, PATH precedence, and removal guidance.
  • Adds --force and HUNK_ALLOW_CONFLICTING_INSTALLS=1 overrides.
  • Expands installer tests and installation documentation.

Confidence Score: 3/5

The PR should not merge until managed-path aliases stop causing false conflicts and candidate version checks cannot block the installer indefinitely.

Conflict discovery currently relies on lexical path equality and synchronously executes every discovered candidate, allowing valid self-installs to be rejected and a single blocking executable to stall installation.

Files Needing Attention: install.sh

Important Files Changed

Filename Overview
install.sh Adds comprehensive conflict discovery and refusal behavior, but lexical target comparison can reject the managed binary and unbounded candidate execution can hang installation.
scripts/install-sh.test.ts Adds coverage for visible and inactive-nvm conflicts, PATH precedence, and forced installation, but does not cover aliased managed paths or non-terminating candidates.
website/src/content/docs/docs/start/install.md Documents the new conflict policy and explicit override consistently with the installer.
.changeset/quiet-install-conflicts.md Accurately records the installer behavior as a patch-level change.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  Start[Installer starts] --> Resolve[Resolve target binary]
  Resolve --> Scan[Scan PATH and inactive nvm/mise installs]
  Scan --> Candidates{Competing candidates found?}
  Candidates -- No --> Version[Check managed target version]
  Candidates -- Yes --> Forced{Force enabled?}
  Forced -- Yes --> Version
  Forced -- No --> Report[Report paths, versions, precedence, and removal guidance]
  Report --> Refuse[Refuse installation]
  Version --> Install[Fast path or download and install]
Loading
Prompt To Fix All With AI
### Issue 1
install.sh:160
**Path aliases trigger false conflicts**

When the managed Hunk directory appears on `PATH` through a symlink, relative path, literal tilde, or another lexical alias, the exact-string comparison treats the managed binary as a competing installation, causing a normal install or upgrade to be refused even though no separate Hunk installation exists. This also affects `HUNK_INSTALL_DIR=/`, where `target_binary` becomes `//hunk` while the PATH scan constructs `/hunk`.

### Issue 2
install.sh:261-263
**Candidate checks can hang installation**

When any later PATH entry or known inactive nvm/mise location contains an executable named `hunk` whose `--version` invocation blocks, conflict reporting executes it without a timeout, causing the installer to hang before it can install, report the conflict, or reach the already-current fast path.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "fix(install): refuse conflicting Hunk in..." | Re-trigger Greptile

Comment thread install.sh
# Add one executable path to the newline-delimited conflict list exactly once.
add_hunk_candidate() {
candidate="$1"
[ -x "$candidate" ] || return 0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Path aliases trigger false conflicts

When the managed Hunk directory appears on PATH through a symlink, relative path, literal tilde, or another lexical alias, the exact-string comparison treats the managed binary as a competing installation, causing a normal install or upgrade to be refused even though no separate Hunk installation exists. This also affects HUNK_INSTALL_DIR=/, where target_binary becomes //hunk while the PATH scan constructs /hunk.

Prompt To Fix With AI
This is a comment left during a code review.
Path: install.sh
Line: 160

Comment:
**Path aliases trigger false conflicts**

When the managed Hunk directory appears on `PATH` through a symlink, relative path, literal tilde, or another lexical alias, the exact-string comparison treats the managed binary as a competing installation, causing a normal install or upgrade to be refused even though no separate Hunk installation exists. This also affects `HUNK_INSTALL_DIR=/`, where `target_binary` becomes `//hunk` while the PATH scan constructs `/hunk`.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 3737f97. Candidate and target paths now resolve physical directory aliases and executable symlink chains before comparison, and root installs construct /hunk rather than //hunk. Added regression coverage for a PATH symlink to the managed binary.

Responded by Pi using openai/gpt-5.6-sol.

This comment was generated by Pi using GPT-5.6 Sol

Comment thread install.sh
Comment on lines +261 to +263
printf '%s\n' "$hunk_candidates" | while IFS= read -r candidate; do
candidate_version="$(installed_version "$candidate")"
[ -n "$candidate_version" ] || candidate_version="unknown"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Candidate checks can hang installation

When any later PATH entry or known inactive nvm/mise location contains an executable named hunk whose --version invocation blocks, conflict reporting executes it without a timeout, causing the installer to hang before it can install, report the conflict, or reach the already-current fast path.

Prompt To Fix With AI
This is a comment left during a code review.
Path: install.sh
Line: 261-263

Comment:
**Candidate checks can hang installation**

When any later PATH entry or known inactive nvm/mise location contains an executable named `hunk` whose `--version` invocation blocks, conflict reporting executes it without a timeout, causing the installer to hang before it can install, report the conflict, or reach the already-current fast path.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not changing this one. A portable POSIX-sh timeout requires launching and killing extra background processes, and the attempted watchdog adds process-lifecycle hazards of its own. The installer already executes the managed target’s --version; the added probes are limited to executable hunk candidates on PATH and known Hunk manager layouts. A deliberately blocking executable at one of those locations is outside the conflict detector’s trust boundary and can be removed or bypassed with --force.

Responded by Pi using openai/gpt-5.6-sol.

This comment was generated by Pi using GPT-5.6 Sol

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That’s a reasonable trade-off for a portable POSIX installer. The conflict probes are intentionally limited to executable Hunk paths the installer already treats as competing installs, and --force returns before invoking those candidates for version reporting. I’ll consider this concern addressed.

@benvinegar
benvinegar merged commit e9726c4 into main Aug 31, 2026
14 checks passed
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