Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 25 additions & 33 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,6 @@ is_wsl() {
[[ -n "${WSL_DISTRO_NAME:-}" ]] || grep -qiE 'microsoft|wsl' /proc/version 2>/dev/null
}

download_with_retry() {
local url="$1"
local dest="$2"
local attempt=1

while [[ ${attempt} -le ${MAX_DOWNLOAD_RETRIES} ]]; do
if curl -fsSL "${url}" -o "${dest}" 2>/dev/null; then
return 0
fi
attempt=$((attempt + 1))
[[ ${attempt} -le ${MAX_DOWNLOAD_RETRIES} ]] && sleep 1
done
return 1
}

cleanup_temp() {
[[ -n "${TEMP_DIR}" ]] && [[ -d "${TEMP_DIR}" ]] && rm -rf "${TEMP_DIR}"
Expand Down Expand Up @@ -134,12 +120,11 @@ check_bash_version() {
}

generate_timestamp() {
# shellcheck disable=SC2312
date +%s%N 2>/dev/null || echo "$(date +%s).$$"
date +%s%N 2>/dev/null || date +%s
}

extract_version() {
local -r cmd="$1"
local cmd="$1"
"${cmd}" --version 2>/dev/null | grep -oE '[0-9.]+' | head -n1 || echo 'found'
}

Expand Down Expand Up @@ -178,23 +163,22 @@ check_dependencies() {
return 1
fi

local v_curl v_claude v_node v_git
v_curl=$(extract_version curl); v_claude=$(extract_version claude)
v_node=$(extract_version node); v_git=$(extract_version git)
success "bash ${BASH_VERSION}"
# shellcheck disable=SC2312
success "curl $(extract_version curl)"
# shellcheck disable=SC2312
success "claude $(extract_version claude)"
# shellcheck disable=SC2312
success "node $(extract_version node)"
# shellcheck disable=SC2312
success "git $(extract_version git)"
success "curl ${v_curl}"
success "claude ${v_claude}"
success "node ${v_node}"
success "git ${v_git}"
# shellcheck disable=SC2310
is_wsl && muted " Detected: WSL environment"

return 0
}

show_install_instructions() {
local -r deps=("$@")
local deps=("$@")
local platform
# shellcheck disable=SC2312
platform=$(uname -s 2>/dev/null || echo "Unknown")
Expand Down Expand Up @@ -244,11 +228,19 @@ show_install_instructions() {
}

download_file() {
local -r url="$1"
local -r dest="$2"
local url="$1"
local dest="$2"
local attempt=1

# shellcheck disable=SC2310
if ! download_with_retry "${url}" "${dest}"; then
while [[ ${attempt} -le ${MAX_DOWNLOAD_RETRIES} ]]; do
if curl -fsSL "${url}" -o "${dest}" 2>/dev/null; then
break
fi
attempt=$((attempt + 1))
[[ ${attempt} -le ${MAX_DOWNLOAD_RETRIES} ]] && sleep 1
done

if [[ ${attempt} -gt ${MAX_DOWNLOAD_RETRIES} ]]; then
error "Failed to download from ${url}"
echo " ${ARROW} Check your internet connection and try again" >&2
return 1
Expand All @@ -262,7 +254,7 @@ download_file() {
}

validate_file() {
local -r file="$1"
local file="$1"

if [[ ! -s "${file}" ]]; then
error "File does not exist or is empty"
Expand Down Expand Up @@ -438,7 +430,7 @@ prompt_component_selection() {
# ============================================================================

install_statusline() {
local -r source="$1"
local source="$1"
local backup=""

if [[ ! -d "${TARGET_DIR}" ]]; then
Expand Down Expand Up @@ -471,7 +463,7 @@ install_statusline() {
}

configure_settings() {
local -r settings_dir="${HOME}/.claude"
local settings_dir="${HOME}/.claude"
local temp_file backup_file

mkdir -p "${settings_dir}" || { error "Cannot create ${settings_dir}"; return 1; }
Expand Down
64 changes: 24 additions & 40 deletions patch-statusline.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,38 +37,34 @@ show_usage() {
echo " $0 statusline.sh messages/es.json --no-cost"
}

# Shared helper: replace the block between start_marker and end_marker in file
# with new_content (pre-built string), then atomically overwrite file.
_replace_marker_block() {
local file="$1" start_marker="$2" end_marker="$3" new_content="$4"
local tmp
tmp=$(mktemp)
sed -n "1,/${start_marker}/p" "${file}" > "${tmp}"
printf '%s\n' "${new_content}" >> "${tmp}"
sed -n "/${end_marker}/,\$p" "${file}" >> "${tmp}"
chmod +x "${tmp}"
mv "${tmp}" "${file}"
}

# Replace @CONFIG_START to @CONFIG_END block
replace_config_block() {
local file="$1"
local show_messages="$2"
local show_cost="$3"
local temp_file
temp_file=$(mktemp)

# Extract everything before @CONFIG_START (inclusive)
sed -n '1,/@CONFIG_START/p' "${file}" > "${temp_file}"

# Insert new config
{
echo "readonly SHOW_MESSAGES=${show_messages}"
echo "readonly SHOW_COST=${show_cost}"
} >> "${temp_file}"

# Extract everything from @CONFIG_END onwards (inclusive)
sed -n '/@CONFIG_END/,$p' "${file}" >> "${temp_file}"

# Preserve original file permissions
chmod --reference="${file}" "${temp_file}" 2>/dev/null || chmod +x "${temp_file}"

mv "${temp_file}" "${file}"
local content
content="readonly SHOW_MESSAGES=${show_messages}
readonly SHOW_COST=${show_cost}"
_replace_marker_block "${file}" '@CONFIG_START' '@CONFIG_END' "${content}"
}

# Replace @MESSAGES_START to @MESSAGES_END block
replace_messages_block() {
local file="$1"
local json_file="$2"
local temp_file
temp_file=$(mktemp)

# Single node call extracts all 5 tiers, one per output line.
# Replicates jq's @sh: wraps each string in single quotes, escaping ' as '\''
Expand All @@ -83,7 +79,6 @@ replace_messages_block() {
});
" "${json_file}") || {
echo "Error: Failed to extract messages from ${json_file}" >&2
rm -f "${temp_file}"
return 1
}

Expand All @@ -95,25 +90,14 @@ replace_messages_block() {
IFS= read -r critical
} <<< "${tier_output}"

# Extract before marker
sed -n '1,/@MESSAGES_START/p' "${file}" > "${temp_file}"

# Insert new arrays (no quotes around ${var} since shell-quoting already applied)
{
echo "readonly CONTEXT_MSG_VERY_LOW=(${very_low})"
echo "readonly CONTEXT_MSG_LOW=(${low})"
echo "readonly CONTEXT_MSG_MEDIUM=(${medium})"
echo "readonly CONTEXT_MSG_HIGH=(${high})"
echo "readonly CONTEXT_MSG_CRITICAL=(${critical})"
} >> "${temp_file}"

# Extract from marker onwards
sed -n '/@MESSAGES_END/,$p' "${file}" >> "${temp_file}"

# Preserve original file permissions
chmod --reference="${file}" "${temp_file}" 2>/dev/null || chmod +x "${temp_file}"
local content
content="readonly CONTEXT_MSG_VERY_LOW=(${very_low})
readonly CONTEXT_MSG_LOW=(${low})
readonly CONTEXT_MSG_MEDIUM=(${medium})
readonly CONTEXT_MSG_HIGH=(${high})
readonly CONTEXT_MSG_CRITICAL=(${critical})"

mv "${temp_file}" "${file}"
_replace_marker_block "${file}" '@MESSAGES_START' '@MESSAGES_END' "${content}"
}

# ============================================================
Expand Down