Skip to content
Open
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
10 changes: 5 additions & 5 deletions lib/cli.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ parse_cli_args() {
# Single parsing loop - each arg goes into exactly ONE bucket
local found_script_command=false

for arg in "${all_args[@]}"; do
for arg in "${all_args[@]:-}"; do
if [[ " ${HOST_ONLY_FLAGS[*]} " == *" $arg "* ]]; then
# Bucket 1: Host-only flags
host_flags+=("$arg")
Expand All @@ -49,15 +49,15 @@ parse_cli_args() {
done

# Export results for use by main script
export CLI_HOST_FLAGS=("${host_flags[@]}")
export CLI_CONTROL_FLAGS=("${control_flags[@]}")
export CLI_HOST_FLAGS=("${host_flags[@]:-}")
export CLI_CONTROL_FLAGS=("${control_flags[@]:-}")
export CLI_SCRIPT_COMMAND="$script_command"
export CLI_PASS_THROUGH=("${pass_through[@]}")
export CLI_PASS_THROUGH=("${pass_through[@]:-}")
}

# Process host-only flags and set environment variables
process_host_flags() {
for flag in "${CLI_HOST_FLAGS[@]}"; do
for flag in "${CLI_HOST_FLAGS[@]:-}"; do
case "$flag" in
--verbose)
export VERBOSE=true
Expand Down
2 changes: 1 addition & 1 deletion lib/commands.clean.sh
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ _cmd_clean() {
cecho "Multiple projects found matching '$search':" "$YELLOW"
echo
local i=1
for match in "${matches[@]}"; do
for match in "${matches[@]:-}"; do
local path="${match%|*}"
local name="${match#*|}"
printf " %d. %s (%s)\n" "$i" "$name" "$path"
Expand Down
4 changes: 2 additions & 2 deletions lib/commands.core.sh
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ _cmd_shell() {
echo "[DEBUG] Remaining args after processing: $*" >&2
fi
# Don't pass any remaining arguments - only shell and the flags
run_claudebox_container "$temp_container" "interactive" shell "${shell_flags[@]}"
run_claudebox_container "$temp_container" "interactive" shell "${shell_flags[@]:-}"

# Commit changes back to image
fillbar
Expand All @@ -127,7 +127,7 @@ _cmd_shell() {
success "Changes saved to image!"
else
# Regular shell mode - just run without committing
run_claudebox_container "" "interactive" shell "${shell_flags[@]}"
run_claudebox_container "" "interactive" shell "${shell_flags[@]:-}"
fi

exit 0
Expand Down
14 changes: 7 additions & 7 deletions lib/commands.profile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ _cmd_add() {

[[ ${#selected[@]} -eq 0 ]] && error "No valid profiles specified\nRun 'claudebox profiles' to see available profiles"

update_profile_section "$profile_file" "profiles" "${selected[@]}"
update_profile_section "$profile_file" "profiles" "${selected[@]:-}"

local all_profiles=()
local all_profiles=()
Expand All @@ -144,7 +144,7 @@ _cmd_add() {

# Check if any Python-related profiles were added
local python_profiles_added=false
for profile in "${selected[@]}"; do
for profile in "${selected[@]:-}"; do
if [[ "$profile" == "python" ]] || [[ "$profile" == "ml" ]] || [[ "$profile" == "datascience" ]]; then
python_profiles_added=true
break
Expand All @@ -162,7 +162,7 @@ _cmd_add() {

# Only show rebuild message for non-Python profiles
local needs_rebuild=false
for profile in "${selected[@]}"; do
for profile in "${selected[@]:-}"; do
if [[ "$profile" != "python" ]] && [[ "$profile" != "ml" ]] && [[ "$profile" != "datascience" ]]; then
needs_rebuild=true
break
Expand All @@ -175,7 +175,7 @@ _cmd_add() {
echo

if [[ ${#remaining[@]} -gt 0 ]]; then
set -- "${remaining[@]}"
set -- "${remaining[@]:-}"
fi
}

Expand Down Expand Up @@ -231,7 +231,7 @@ _cmd_remove() {
local python_profiles_removed=false
for profile in "${current_profiles[@]}"; do
local keep=true
for remove in "${to_remove[@]}"; do
for remove in "${to_remove[@]:-}"; do
if [[ "$profile" == "$remove" ]]; then
keep=false
# Check if we're removing a Python-related profile
Expand All @@ -246,7 +246,7 @@ _cmd_remove() {

# Check if any Python-related profiles remain
local has_python_profiles=false
for profile in "${new_profiles[@]}"; do
for profile in "${new_profiles[@]:-}"; do
if [[ "$profile" == "python" ]] || [[ "$profile" == "ml" ]] || [[ "$profile" == "datascience" ]]; then
has_python_profiles=true
break
Expand Down Expand Up @@ -275,7 +275,7 @@ _cmd_remove() {
# Write back the filtered profiles
{
echo "[profiles]"
for profile in "${new_profiles[@]}"; do
for profile in "${new_profiles[@]:-}"; do
echo "$profile"
done
echo ""
Expand Down
10 changes: 5 additions & 5 deletions lib/commands.system.sh
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ Current directory: $PWD"
if [[ ${#window_panes[@]} -gt 0 ]]; then
# Calculate total slots needed
total_slots_needed=0
for panes in "${window_panes[@]}"; do
for panes in "${window_panes[@]:-}"; do
((total_slots_needed += panes)) || true
done

Expand Down Expand Up @@ -558,7 +558,7 @@ Current directory: $PWD"
local first_created=false

# Create panes one by one, capturing IDs atomically
for panes in "${window_panes[@]}"; do
for panes in "${window_panes[@]:-}"; do
for ((i=0; i<panes; i++)); do
if [[ $slot_index -ge ${#available_slots[@]} ]]; then
error "Not enough available slots for layout"
Expand Down Expand Up @@ -726,7 +726,7 @@ _cmd_project() {
else
# Multiple matches - show them
error "Multiple projects match '$search':"
for match in "${matches[@]}"; do
for match in "${matches[@]:-}"; do
local path="${match%%|*}"
local name="${match##*|}"
echo " $name -> $path"
Expand Down Expand Up @@ -813,7 +813,7 @@ _cmd_import() {
cecho "Available commands to import:" "$CYAN"
echo
local i=1
for cmd in "${commands[@]}"; do
for cmd in "${commands[@]:-}"; do
printf " %2d. %s\n" "$i" "$cmd"
((i++)) || true
done
Expand All @@ -832,7 +832,7 @@ _cmd_import() {
a|A|all|ALL)
# Import all commands
local imported=0
for cmd in "${commands[@]}"; do
for cmd in "${commands[@]:-}"; do
if cp "$host_commands/$cmd" "$project_commands/"; then
((imported++)) || true
fi
Expand Down
10 changes: 5 additions & 5 deletions lib/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ read_profile_section() {
done < <(sed -n "/^\[$section\]/,/^\[/p" "$profile_file" | tail -n +2 | grep -v '^\[')
fi

printf '%s\n' "${result[@]}"
printf '%s\n' "${result[@]:-}"
}

update_profile_section() {
Expand All @@ -143,13 +143,13 @@ update_profile_section() {
readarray -t existing_items < <(read_profile_section "$profile_file" "$section")

local all_items=()
for item in "${existing_items[@]}"; do
for item in "${existing_items[@]:-}"; do
[[ -n "$item" ]] && all_items+=("$item")
done

for item in "${new_items[@]}"; do
for item in "${new_items[@]:-}"; do
local found=false
for existing in "${all_items[@]}"; do
for existing in "${all_items[@]:-}"; do
[[ "$existing" == "$item" ]] && found=true && break
done
[[ "$found" == "false" ]] && all_items+=("$item")
Expand All @@ -169,7 +169,7 @@ update_profile_section() {
fi

echo "[$section]"
for item in "${all_items[@]}"; do
for item in "${all_items[@]:-}"; do
echo "$item"
done
echo ""
Expand Down
6 changes: 3 additions & 3 deletions lib/docker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ run_claudebox_container() {
# Handle "attached" mode - start detached, wait, then attach
if [[ "$run_mode" == "attached" ]]; then
# Start detached
run_claudebox_container "$container_name" "detached" "${container_args[@]}" >/dev/null
run_claudebox_container "$container_name" "detached" "${container_args[@]:-}" >/dev/null

# Show progress while container initializes
fillbar
Expand Down Expand Up @@ -398,14 +398,14 @@ run_claudebox_container() {

# Add any additional arguments
if [[ ${#container_args[@]} -gt 0 ]]; then
docker_args+=("${container_args[@]}")
docker_args+=("${container_args[@]:-}")
fi

# Run the container
if [[ "$VERBOSE" == "true" ]]; then
echo "[DEBUG] Docker run command: docker run ${docker_args[*]}" >&2
fi
docker run "${docker_args[@]}"
docker run "${docker_args[@]:-}"
local exit_code=$?

return $exit_code
Expand Down
4 changes: 2 additions & 2 deletions lib/tools-report.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ generate_tools_report() {
if [[ ${#profiles[@]} -gt 0 ]]; then
echo "## Active Development Profiles"
echo
for profile in "${profiles[@]}"; do
for profile in "${profiles[@]:-}"; do
echo "### $profile"
echo
_describe_profile "$profile"
Expand Down Expand Up @@ -66,7 +66,7 @@ generate_tools_report() {
echo
echo "The following custom packages have been installed:"
echo
for package in "${packages[@]}"; do
for package in "${packages[@]:-}"; do
echo "- $package"
done
echo
Expand Down
32 changes: 16 additions & 16 deletions main.sh
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ main() {
if [[ ${#saved_flags[@]} -gt 0 ]]; then
# Re-parse WITH saved flags, but the command structure is preserved
# because the command was already identified from original args
parse_cli_args "${original_args[@]}" "${saved_flags[@]}"
parse_cli_args "${original_args[@]:-}" "${saved_flags[@]:-}"
process_host_flags

if [[ "$VERBOSE" == "true" ]]; then
Expand Down Expand Up @@ -137,7 +137,7 @@ main() {
# If command doesn't need Docker, skip all Docker setup
if [[ "$cmd_requirements" == "none" ]]; then
# Dispatch the command directly and exit
dispatch_command "${CLI_SCRIPT_COMMAND}" "${CLI_PASS_THROUGH[@]}" "${CLI_CONTROL_FLAGS[@]}"
dispatch_command "${CLI_SCRIPT_COMMAND}" "${CLI_PASS_THROUGH[@]:-}" "${CLI_CONTROL_FLAGS[@]:-}"
exit $?
fi

Expand Down Expand Up @@ -299,7 +299,7 @@ main() {
local cmd_req=$(get_command_requirements "${CLI_SCRIPT_COMMAND}")
# Only run pre-flight for commands that need Docker or image
if [[ "$cmd_req" == "docker" ]] || [[ "$cmd_req" == "image" ]]; then
if ! preflight_check "${CLI_SCRIPT_COMMAND}" "${CLI_PASS_THROUGH[@]}"; then
if ! preflight_check "${CLI_SCRIPT_COMMAND}" "${CLI_PASS_THROUGH[@]:-}"; then
# Pre-flight check failed and printed error
exit 1
fi
Expand Down Expand Up @@ -353,9 +353,9 @@ main() {
local docker_profiles=()
local python_only_profiles=("python" "ml" "datascience")

for profile in "${current_profiles[@]}"; do
for profile in "${current_profiles[@]:-}"; do
local is_python_only=false
for py_profile in "${python_only_profiles[@]}"; do
for py_profile in "${python_only_profiles[@]:-}"; do
if [[ "$profile" == "$py_profile" ]]; then
is_python_only=true
break
Expand All @@ -369,7 +369,7 @@ main() {
# Calculate hash only for Docker-affecting profiles
local docker_profiles_hash=""
if [[ ${#docker_profiles[@]} -gt 0 ]]; then
docker_profiles_hash=$(printf '%s\n' "${docker_profiles[@]}" | sort | cksum | cut -d' ' -f1)
docker_profiles_hash=$(printf '%s\n' "${docker_profiles[@]:-}" | sort | cksum | cut -d' ' -f1)
fi

local image_profiles_hash=$(docker inspect "$IMAGE_NAME" --format '{{index .Config.Labels "claudebox.profiles"}}' 2>/dev/null || echo "")
Expand Down Expand Up @@ -426,7 +426,7 @@ main() {
if [[ -n "${CLI_SCRIPT_COMMAND}" ]]; then
# Script command - dispatch on host
# Pass control flags and pass-through args to dispatch_command
dispatch_command "${CLI_SCRIPT_COMMAND}" "${CLI_PASS_THROUGH[@]}" "${CLI_CONTROL_FLAGS[@]}"
dispatch_command "${CLI_SCRIPT_COMMAND}" "${CLI_PASS_THROUGH[@]:-}" "${CLI_CONTROL_FLAGS[@]:-}"
exit $?
else
# No script command - running Claude interactively
Expand Down Expand Up @@ -456,10 +456,10 @@ main() {
# Re-parse all arguments with saved flags included
if [[ ${#saved_flags[@]} -gt 0 ]]; then
# Combine original args with saved flags
local all_args=("${original_args[@]}" "${saved_flags[@]}")
local all_args=("${original_args[@]:-}" "${saved_flags[@]:-}")

# Re-parse to properly sort flags
parse_cli_args "${all_args[@]}"
parse_cli_args "${all_args[@]:-}"
process_host_flags

if [[ "$VERBOSE" == "true" ]]; then
Expand All @@ -472,7 +472,7 @@ main() {
# Check if stdin is not a terminal (i.e., we're receiving piped input)
# and -p/--print flag isn't already present
local has_print_flag=false
for arg in "${CLI_PASS_THROUGH[@]}"; do
for arg in "${CLI_PASS_THROUGH[@]:-}"; do
if [[ "$arg" == "-p" ]] || [[ "$arg" == "--print" ]]; then
has_print_flag=true
break
Expand All @@ -495,9 +495,9 @@ main() {
fi
local piped_input
piped_input=$(cat)
run_claudebox_container "$container_name" "interactive" "${CLI_CONTROL_FLAGS[@]}" "-p" "$piped_input" "${CLI_PASS_THROUGH[@]}"
run_claudebox_container "$container_name" "interactive" "${CLI_CONTROL_FLAGS[@]:-}" "-p" "$piped_input" "${CLI_PASS_THROUGH[@]:-}"
else
run_claudebox_container "$container_name" "interactive" "${CLI_CONTROL_FLAGS[@]}" "${CLI_PASS_THROUGH[@]}"
run_claudebox_container "$container_name" "interactive" "${CLI_CONTROL_FLAGS[@]:-}" "${CLI_PASS_THROUGH[@]:-}"
fi
else
show_no_slots_menu
Expand Down Expand Up @@ -537,7 +537,7 @@ build_docker_image() {
done < <(read_profile_section "$profiles_file" "profiles")

# Generate profile installations
for profile in "${current_profiles[@]}"; do
for profile in "${current_profiles[@]:-}"; do
profile=$(echo "$profile" | tr -d '[:space:]')
[[ -z "$profile" ]] && continue

Expand All @@ -552,9 +552,9 @@ build_docker_image() {
local docker_profiles=()
local python_only_profiles=("python" "ml" "datascience")

for profile in "${current_profiles[@]}"; do
for profile in "${current_profiles[@]:-}"; do
local is_python_only=false
for py_profile in "${python_only_profiles[@]}"; do
for py_profile in "${python_only_profiles[@]:-}"; do
if [[ "$profile" == "$py_profile" ]]; then
is_python_only=true
break
Expand All @@ -566,7 +566,7 @@ build_docker_image() {
done

if [[ ${#docker_profiles[@]} -gt 0 ]]; then
profile_hash=$(printf '%s\n' "${docker_profiles[@]}" | sort | cksum | cut -d' ' -f1)
profile_hash=$(printf '%s\n' "${docker_profiles[@]:-}" | sort | cksum | cut -d' ' -f1)
fi
fi

Expand Down
2 changes: 1 addition & 1 deletion tooling/profiles/rust.sh
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ CARGO_TOOLS=(
"hyperfine"
)

for tool in "${CARGO_TOOLS[@]}"; do
for tool in "${CARGO_TOOLS[@]:-}"; do
if ! command -v "$tool" >/dev/null 2>&1; then
echo "Installing $tool..."
cargo install "$tool"
Expand Down