Skip to content

Fix: make curl | bash install work (empty BASH_SOURCE on stdin)#2

Merged
ehlersd merged 1 commit into
mainfrom
fix/curl-bash-piped-install
May 23, 2026
Merged

Fix: make curl | bash install work (empty BASH_SOURCE on stdin)#2
ehlersd merged 1 commit into
mainfrom
fix/curl-bash-piped-install

Conversation

@ehlersd
Copy link
Copy Markdown
Member

@ehlersd ehlersd commented May 23, 2026

Summary

The advertised one-line install never worked:

curl -fsSL .../scripts/install.sh | bash
# bash: line 19: BASH_SOURCE[0]: unbound variable
# ERROR: Hook source not found: <cwd-parent>/hooks/inject-time-context.sh

install.sh located its hook sources via ${BASH_SOURCE[0]} relative to its own file. When piped through curl ... | bash the script is read from stdin — there is no file, so BASH_SOURCE is empty. Under set -u (line 14) that referencing aborts with BASH_SOURCE[0]: unbound variable, and the derived REPO_ROOT collapses to the parent of the caller's cwd, so the sibling hooks/ lookup fails. The only working path was the "Manual Install" (clone + run).

Changes

File Change
scripts/install.sh Guard ${BASH_SOURCE[0]:-}; new install_hook() copies from a local checkout when present, otherwise downloads the hook scripts. Adds CLAUDE_CONTEXT_TICK_REF (default main) and CLAUDE_CONTEXT_TICK_RAW_BASE (mirror/test override).
tests/test_install_piped.sh New hermetic regression: runs the installer via stdin (reproduces empty BASH_SOURCE) and resolves downloads from the local checkout via a file:// base — no network.
README.md One-liner now honest; documents CLAUDE_CONTEXT_TICK_REF; security note updated (it downloads two hook scripts + merges settings).
CHANGELOG.md Fixed + Added entries under [Unreleased].

Risk

LOW. uninstall.sh was unaffected (uses fixed $HOME/.claude/ paths). The settings.json merge/idempotency logic is unchanged. The checkout-install path keeps copying from hooks/ exactly as before.

Testing

  • Full suite: 10/10 pass (macOS), including the new test_install_piped.
  • Manual, in throwaway sandbox HOMEs:
    • Piped + real network (the exact failing scenario) → downloads both hooks, creates settings.json, registers UserPromptSubmit + SessionEnd, exit 0.
    • Checkout install (bash scripts/install.sh) → cp path, exit 0.
  • shellcheck scripts/install.sh clean.

Checklist

  • Tests pass locally (and CI runs macOS + Ubuntu)
  • shellcheck clean on changed script
  • Contribution includes a test case (per README)
  • Self-reviewed

🤖 Generated with Claude Code

The installer resolved its hook sources via ${BASH_SOURCE[0]} relative to
its own file. Piped through `curl ... | bash`, the script is read from
stdin: BASH_SOURCE is empty, so under `set -u` it aborted with
"BASH_SOURCE[0]: unbound variable" and then failed to find the sibling
hooks/ directory — making the advertised one-line install impossible.

- Guard ${BASH_SOURCE[0]:-} so set -u no longer crashes on stdin.
- install_hook(): copy from a local checkout when present, otherwise
  download the hook scripts from the repo.
- CLAUDE_CONTEXT_TICK_REF (default main) pins the download ref;
  CLAUDE_CONTEXT_TICK_RAW_BASE overrides the base URL (mirror/tests).
- Add tests/test_install_piped.sh: hermetic regression (stdin +
  file:// base, no network).
- Update README security note + CHANGELOG.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ehlersd ehlersd merged commit 2de374b into main May 23, 2026
4 checks passed
@ehlersd ehlersd deleted the fix/curl-bash-piped-install branch May 23, 2026 20:19
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