# =============================================================================
# CUSTOM FUNCTIONS
# =============================================================================

# -----------------------------------------------------------------------------
# Function: funcs (List available .func functions)
# -----------------------------------------------------------------------------
funcs() {
  local func_file="${1:-$HOME/.func}"

  if [ ! -f "$func_file" ]; then
    printf "Error: Function file '%s' not found.\n" "$func_file" >&2
    return 1
  fi

  printf "Available functions in %s:\n" "$func_file"
  awk '
    /^# Function: / {
      line = $0
      sub(/^# Function: /, "", line)

      name = line
      sub(/ .*/, "", name)

      desc = ""
      if (line ~ / \(.+\)$/) {
        desc = line
        sub(/^[^ ]+ \(/, "", desc)
        sub(/\)$/, "", desc)
      }

      if (desc != "") {
        printf "  %-22s %s\n", name, desc
      } else {
        printf "  %s\n", name
      }
    }
  ' "$func_file"
}

# -----------------------------------------------------------------------------
# Function: clip (Cross-platform clipboard)
# -----------------------------------------------------------------------------
clip() {
  local cmd
  local args=()

  if command -v pbcopy >/dev/null 2>&1; then
    cmd="pbcopy" # macOS
  elif grep -qi "microsoft" /proc/version 2>/dev/null && command -v clip.exe >/dev/null 2>&1; then
    cmd="clip.exe" # WSL
  elif [ "$XDG_SESSION_TYPE" = "wayland" ] && command -v wl-copy >/dev/null 2>&1; then
    cmd="wl-copy" # Linux Wayland
  elif command -v xclip >/dev/null 2>&1; then
    cmd="xclip" # Linux X11 (Fallback 1)
    args=("-selection" "clipboard")
  elif command -v xsel >/dev/null 2>&1; then
    cmd="xsel" # Linux X11 (Fallback 2)
    args=("--clipboard" "--input")
  else
    printf "Error: No supported clipboard utility found.\n" >&2
    return 1
  fi

  if [ $# -gt 0 ]; then
    if [ -f "$1" ]; then
      "$cmd" "${args[@]}" < "$1"
      echo "Copied contents of '$1' to clipboard."
    else
      printf "Error: File '%s' not found.\n" "$1" >&2
      return 1
    fi
  else
    "$cmd" "${args[@]}"
  fi
}

# -----------------------------------------------------------------------------
# Function: open_file (Cross-platform file/directory opener)
# -----------------------------------------------------------------------------
open_file() {
    local target="${1:-.}"
    
    if [[ "$OSTYPE" == "darwin"* ]]; then
        command open "$target"
    elif grep -qi "microsoft" /proc/version 2>/dev/null; then
        if command -v wslpath >/dev/null 2>&1 && command -v explorer.exe >/dev/null 2>&1; then
            explorer.exe "$(wslpath -w "$target")"
        else
            printf "Error: 'wslpath' or 'explorer.exe' not found.\n" >&2
            return 1
        fi
    elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
        if command -v xdg-open >/dev/null 2>&1; then
            xdg-open "$target"
        else
            printf "Error: 'xdg-open' not found.\n" >&2
            return 1
        fi
    fi
}
alias open='open_file'

# -----------------------------------------------------------------------------
# Function: clear_history (Supports shell, Claude, Codex, and OpenCode)
# -----------------------------------------------------------------------------
clear_history() {
  case "${1:-}" in
    claude)
      if [ -d "$HOME/.claude/projects" ]; then
        # Use 'yes' to skip prompts and -f to ignore non-existent files
        yes | rm -rf "$HOME/.claude/projects"/*
        echo "Claude project history/cache cleared."
      fi
      ;;

    codex)
      local codex_home="${CODEX_HOME:-$HOME/.codex}"
      local codex_session_file
      local codex_session_id

      mkdir -p "$codex_home"
      : > "$codex_home/history.jsonl"

      if command -v codex >/dev/null 2>&1; then
        find "$codex_home/sessions" "$codex_home/archived_sessions" -type f -name '*.jsonl' -print 2>/dev/null | while IFS= read -r codex_session_file; do
          codex_session_id="$(sed -n 's/.*"session_id":"\([^"]*\)".*/\1/p; q' "$codex_session_file")"
          if [ -n "$codex_session_id" ]; then
            codex delete --force "$codex_session_id" >/dev/null 2>&1 || true
          fi
        done
      fi

      rm -rf "$codex_home/sessions" "$codex_home/archived_sessions" "$codex_home/shell_snapshots"
      mkdir -p "$codex_home/sessions" "$codex_home/archived_sessions" "$codex_home/shell_snapshots"

      echo "Codex history cleared."
      ;;

    opencode)
      local opencode_state_home="${XDG_STATE_HOME:-$HOME/.local/state}/opencode"
      local opencode_data_home="${XDG_DATA_HOME:-$HOME/.local/share}/opencode"

      mkdir -p "$opencode_state_home" "$opencode_data_home"
      : > "$opencode_state_home/prompt-history.jsonl"
      rm -f \
        "$opencode_data_home/opencode.db" \
        "$opencode_data_home/opencode.db-shm" \
        "$opencode_data_home/opencode.db-wal"
      rm -rf "$opencode_data_home/repos" "$opencode_data_home/log"
      mkdir -p "$opencode_data_home/repos" "$opencode_data_home/log"

      echo "OpenCode history cleared."
      ;;

    *)
      # 1. Truncate the file
      : > "$HISTFILE" 

      # 2. Clear RAM by briefly setting history size to 0
      local old_histsize=$HISTSIZE
      HISTSIZE=0
      HISTSIZE=$old_histsize
      
      echo "Shell history cleared."
      ;;
  esac
}

# -----------------------------------------------------------------------------
# Function: require_cli (Check external CLI availability)
# -----------------------------------------------------------------------------
require_cli() {
  local binary="$1"
  local label="$2"
  local resolved

  if command -v whence >/dev/null 2>&1; then
    if whence -p "$binary" >/dev/null 2>&1; then
      return 0
    fi
  else
    resolved="$(command -v "$binary" 2>/dev/null)" || resolved=""
    if [ -n "$resolved" ] && [ -x "$resolved" ]; then
      return 0
    fi
  fi

  printf "Error: %s ('%s') is not installed or not in your PATH.\n" "$label" "$binary" >&2
  return 1
}

# -----------------------------------------------------------------------------
# Function: claude (Includes --yolo and clear shortcuts)
# -----------------------------------------------------------------------------
claude() {
  # Shortcut for clearing cache
  if [[ "$1" == "clear" ]]; then
    clear_history claude
    return 0
  fi

  # Check if binary exists
  require_cli claude "Claude Code CLI" || return 1

  # Handle --yolo mode
  if [[ "$1" == "--yolo" ]]; then
    shift
    command claude --dangerously-skip-permissions "$@"
    return $?
  fi

  command claude "$@"
}

# -----------------------------------------------------------------------------
# Internal: _prompt_confirm_indexing (Confirm project indexing via the terminal)
# -----------------------------------------------------------------------------
_prompt_confirm_indexing() {
  local project_root="$1"
  local reply

  if ! (: </dev/tty) 2>/dev/null; then
    printf "Notice: No interactive terminal available; enhancing without project indexing.\n" >&2
    return 1
  fi

  printf "Allow Auggie to index and use project context from '%s'? (y/N) " "$project_root" >/dev/tty
  if ! IFS= read -r reply </dev/tty; then
    printf "\nNotice: Unable to read confirmation; enhancing without project indexing.\n" >&2
    return 1
  fi

  case "$reply" in
    y|Y|yes|YES|Yes)
      return 0
      ;;
    *)
      return 1
      ;;
  esac
}

# -----------------------------------------------------------------------------
# Internal: _enhance_prompt (Run Auggie and write only the enhanced prompt)
# -----------------------------------------------------------------------------
_enhance_prompt() {
  local prompt="$1"
  local output_file="$2"
  local run_dir
  local prompt_file
  local workspace
  local cache_dir
  local auth_file
  local log_file
  local parsed_file
  local project_root
  local use_project_context
  local script_pid
  local waited
  local timeout_seconds
  local monitor_status

  if [ -z "$prompt" ]; then
    printf "Error: Prompt was empty.\n" >&2
    return 1
  fi

  if [ ! -s "$HOME/.augment/session.json" ]; then
    printf "Error: Auggie session file not found. Run 'auggie login' first.\n" >&2
    return 1
  fi

  run_dir="$(mktemp -d "${TMPDIR:-/tmp}/auggie-enhance.XXXXXX")" || return 1
  prompt_file="$run_dir/prompt.txt"
  workspace="$run_dir/workspace"
  cache_dir="$run_dir/cache"
  auth_file="$HOME/.augment/session.json"
  log_file="$run_dir/auggie.log"
  parsed_file="$run_dir/enhanced.txt"
  mkdir -p "$workspace" "$cache_dir"
  printf "%s\n" "$prompt" > "$prompt_file"

  project_root="$(git rev-parse --show-toplevel 2>/dev/null)" || project_root="$PWD"
  use_project_context=0
  timeout_seconds=90

  if _prompt_confirm_indexing "$project_root"; then
    use_project_context=1
    timeout_seconds=300
    workspace="$project_root"
    cache_dir="$HOME/.augment"
    printf "Indexing approved; enhancing with project context from '%s'.\n" "$project_root" >&2
  else
    printf "Enhancing without project indexing.\n" >&2
  fi

  (
    if [ "$use_project_context" -eq 1 ]; then
      AUGGIE_PROMPT_FILE="$prompt_file" \
      AUGGIE_WORKSPACE="$workspace" \
      AUGGIE_CACHE_DIR="$cache_dir" \
      AUGGIE_AUTH_FILE="$auth_file" \
        script -q -f -O "$log_file" -c 'auggie --print --enhance-prompt --workspace-root "$AUGGIE_WORKSPACE" --augment-cache-dir "$AUGGIE_CACHE_DIR" --augment-session-json "$AUGGIE_AUTH_FILE" --allow-indexing --wait-for-indexing --dont-save-session --instruction-file "$AUGGIE_PROMPT_FILE"' </dev/null >/dev/null 2>&1 &
    else
      AUGGIE_PROMPT_FILE="$prompt_file" \
      AUGGIE_WORKSPACE="$workspace" \
      AUGGIE_CACHE_DIR="$cache_dir" \
      AUGGIE_AUTH_FILE="$auth_file" \
        script -q -f -O "$log_file" -c 'auggie --print --enhance-prompt --no-discover-workspaces --workspace-root "$AUGGIE_WORKSPACE" --augment-cache-dir "$AUGGIE_CACHE_DIR" --augment-session-json "$AUGGIE_AUTH_FILE" --dont-save-session --instruction-file "$AUGGIE_PROMPT_FILE"' </dev/null >/dev/null 2>&1 &
    fi

    script_pid=$!
    waited=0

    while kill -0 "$script_pid" >/dev/null 2>&1; do
      if grep -aq "🤖" "$log_file" 2>/dev/null || grep -aq "Tool call:" "$log_file" 2>/dev/null; then
        kill "$script_pid" >/dev/null 2>&1 || true
        wait "$script_pid" >/dev/null 2>&1 || true
        exit 0
      fi

      if [ "$waited" -ge "$timeout_seconds" ]; then
        kill "$script_pid" >/dev/null 2>&1 || true
        wait "$script_pid" >/dev/null 2>&1 || true
        exit 124
      fi

      sleep 1
      waited=$((waited + 1))
    done

    wait "$script_pid" >/dev/null 2>&1 || true
    exit 0
  )
  monitor_status=$?

  if [ "$monitor_status" -eq 124 ]; then
    printf "Error: Timed out waiting for Auggie to enhance the prompt.\n" >&2
    rm -rf "$run_dir"
    return 124
  fi

  perl -ne '
    # Auggie redraws streamed terminal lines with carriage returns. Keep only
    # the final rendered segment so stale text cannot corrupt the prompt.
    s/\r$//;
    s/.*\r//;
    1 while s/[^\x08]\x08//g;
    s/\x08//g;
    s/\e\][^\a]*(?:\a|\e\\)//g;
    s/\e\[[0-?]*[ -\/]*[@-~]//g;
    next if /Script started on/ || /Script done on/;
    if (/^(?:✨\s*)?Enhanced prompt:\s*(.*)$/) {
      $capturing = 1;
      $output .= "$1\n" if length $1;
      next;
    }
    next unless $capturing;
    exit if /^🤖/ || /Tool call:/ || /Session terminated/;
    $output .= $_;
    END {
      $output =~ s/^\s*\n//;
      $output =~ s/\s+\z//;
      print "$output\n" if length $output;
    }
  ' "$log_file" > "$parsed_file"

  if [ ! -s "$parsed_file" ]; then
    printf "Error: Auggie did not return an enhanced prompt.\n" >&2
    rm -rf "$run_dir"
    return 1
  fi

  if ! command cp "$parsed_file" "$output_file"; then
    printf "Error: Unable to save the enhanced prompt.\n" >&2
    rm -rf "$run_dir"
    return 1
  fi
  rm -rf "$run_dir"
}

# -----------------------------------------------------------------------------
# Function: prompt (Enhance a prompt with Auggie and optional project context)
# -----------------------------------------------------------------------------
prompt() {
  local prompt
  local line
  local output_file

  require_cli auggie "Auggie CLI" || return 1
  require_cli script "script utility" || return 1

  if [ $# -gt 0 ]; then
    prompt="$*"
  elif [ ! -t 0 ]; then
    prompt="$(cat)"
  else
    echo "Reading prompt... Type 'EOF' on a new line and press Enter when finished."
    prompt=""

    while IFS= read -r line; do
      [ "$line" = "EOF" ] && break
      if [ -z "$prompt" ]; then
        prompt="$line"
      else
        prompt="${prompt}"$'\n'"${line}"
      fi
    done
  fi

  if [ -z "$prompt" ]; then
    printf "Error: Prompt was empty.\n" >&2
    return 1
  fi

  output_file="$(mktemp "${TMPDIR:-/tmp}/auggie-enhanced-prompt.XXXXXX")" || return 1
  if ! _enhance_prompt "$prompt" "$output_file"; then
    rm -f "$output_file"
    return 1
  fi

  if [ -t 1 ]; then
    clear
  fi

  printf "Enhanced prompt:\n"
  command cat "$output_file"
  rm -f "$output_file"

  command auggie account status
}

# -----------------------------------------------------------------------------
# Function: plan_build (Cached canonical plan-build launcher)
# -----------------------------------------------------------------------------
plan_build() {
  emulate -L zsh
  setopt localtraps
  local base_url="${PLAN_BUILD_BASE_URL:-https://opengist.resetrix.work/weehong/plan-build/raw/HEAD}"
  local cache_dir="${PLAN_BUILD_CACHE_DIR:-${XDG_CACHE_HOME:-$HOME/.cache}/plan-build}"
  local curl_command="${PLAN_BUILD_CURL_COMMAND:-curl}"
  local skill_file="$HOME/.claude/skills/plan-build/SKILL.md"
  local architect_file="$HOME/.claude/skills/plan-build-architect/SKILL.md"
  local stage_dir="" release_dir="" current_tmp=""
  local skill_tmp="" architect_tmp="" skill_backup="" architect_backup=""
  local activation_lock="$cache_dir/.activate.lock"
  local activation_lock_fd=""
  local selected_release="" active_pid="" refresh_rc=1 call_rc=0 interrupted_rc=0

  if ! zmodload zsh/system 2>/dev/null; then
    printf "Error: Unable to load the Zsh system module required by plan-build.\n" >&2
    return 1
  fi

  require_cli zsh "Zsh" || return 1

  if ! command mkdir -p "$cache_dir" "${skill_file:h}" "${architect_file:h}"; then
    printf "Error: Unable to create plan-build cache or skill directories.\n" >&2
    return 1
  fi

  _plan_build_cleanup() {
    if [[ -n "${active_pid:-}" ]] && command kill -0 "$active_pid" 2>/dev/null; then
      command kill "$active_pid" 2>/dev/null || true
      wait "$active_pid" 2>/dev/null || true
    fi
    active_pid=""
    [[ -n "$stage_dir" && -d "$stage_dir" ]] && command rm -rf -- "$stage_dir"
    command rm -f -- "$current_tmp" "$skill_tmp" "$architect_tmp"
    command rm -f -- "$skill_backup" "$architect_backup"
    if [[ -n "${activation_lock_fd:-}" ]]; then
      zsystem flock -u "$activation_lock_fd" 2>/dev/null || true
      activation_lock_fd=""
    fi
  }
  _plan_build_cancel() {
    interrupted_rc="$1"
    [[ -n "${active_pid:-}" ]] && command kill "$active_pid" 2>/dev/null || true
  }
  trap '_plan_build_cleanup' EXIT
  trap '_plan_build_cancel 129' HUP
  trap '_plan_build_cancel 130' INT
  trap '_plan_build_cancel 143' TERM

  _plan_build_validate_release() {
    local candidate="$1"
    [[ -d "$candidate" &&
       -s "$candidate/plan_build.zsh" &&
       -s "$candidate/SKILL.md" &&
       -s "$candidate/ARCHITECT.md" ]] &&
      command zsh -n "$candidate/plan_build.zsh"
  }

  _plan_build_replace_path() {
    local replacement="$1" destination="$2"
    if command mv -fT "$replacement" "$destination" 2>/dev/null; then
      return 0
    fi
    command mv -fh "$replacement" "$destination"
  }

  _plan_build_select_current() {
    local resolved
    [[ -L "$cache_dir/current" ]] || return 1
    resolved="$cache_dir/current"
    resolved="${resolved:A}"
    _plan_build_validate_release "$resolved" || return 1
    selected_release="$resolved"
  }

  _plan_build_acquire_activation_lock() {
    (( interrupted_rc )) && return 1
    command touch "$activation_lock" || return 1
    zsystem flock -t 10 -f activation_lock_fd "$activation_lock"
  }

  _plan_build_release_activation_lock() {
    [[ -n "$activation_lock_fd" ]] || return 0
    zsystem flock -u "$activation_lock_fd" || return 1
    activation_lock_fd=""
  }

  _plan_build_download() {
    local remote="$1" destination="$2" download_rc
    command "$curl_command" -fsSL "$remote" -o "$destination" &
    active_pid=$!
    wait "$active_pid"
    download_rc=$?
    active_pid=""
    (( interrupted_rc )) && return "$interrupted_rc"
    return "$download_rc"
  }

  _plan_build_backup_path() {
    local source="$1" backup="$2"
    [[ -e "$source" || -L "$source" ]] || return 0
    command rm -f -- "$backup" && command cp -RP "$source" "$backup"
  }

  _plan_build_restore_path() {
    local destination="$1" backup="$2" had_old="$3"
    if (( had_old )); then
      _plan_build_replace_path "$backup" "$destination" || return 1
    else
      command rm -f -- "$destination"
    fi
  }

  _plan_build_install_skill_links() {
    local activation_ok=1
    local skill_had_old=0 architect_had_old=0

    skill_tmp="$(command mktemp "${skill_file}.link.XXXXXX")" &&
      command rm -f "$skill_tmp" &&
      command ln -s "$cache_dir/current/SKILL.md" "$skill_tmp" || skill_tmp=""
    architect_tmp="$(command mktemp "${architect_file}.link.XXXXXX")" &&
      command rm -f "$architect_tmp" &&
      command ln -s "$cache_dir/current/ARCHITECT.md" "$architect_tmp" || architect_tmp=""
    [[ -n "$skill_tmp" && -L "$skill_tmp" &&
       -n "$architect_tmp" && -L "$architect_tmp" ]] || return 1

    skill_backup="${skill_file}.backup.$$.$RANDOM"
    architect_backup="${architect_file}.backup.$$.$RANDOM"
    [[ -e "$skill_file" || -L "$skill_file" ]] && skill_had_old=1
    [[ -e "$architect_file" || -L "$architect_file" ]] && architect_had_old=1
    _plan_build_backup_path "$skill_file" "$skill_backup" || activation_ok=0
    (( activation_ok )) && _plan_build_backup_path "$architect_file" "$architect_backup" || activation_ok=0
    (( activation_ok && ! interrupted_rc )) &&
      _plan_build_replace_path "$skill_tmp" "$skill_file" || activation_ok=0
    (( activation_ok )) && skill_tmp=""
    (( activation_ok && ! interrupted_rc )) &&
      _plan_build_replace_path "$architect_tmp" "$architect_file" || activation_ok=0
    (( activation_ok )) && architect_tmp=""

    if (( activation_ok )); then
      command rm -f -- "$skill_backup" "$architect_backup"
      skill_backup="" architect_backup=""
      return 0
    fi

    if ! _plan_build_restore_path "$skill_file" "$skill_backup" "$skill_had_old"; then
      printf "Error: Unable to restore plan-build skill; backup preserved at %s.\n" "$skill_backup" >&2
      skill_backup=""
    fi
    if ! _plan_build_restore_path "$architect_file" "$architect_backup" "$architect_had_old"; then
      printf "Error: Unable to restore architect skill; backup preserved at %s.\n" "$architect_backup" >&2
      architect_backup=""
    fi
    return 1
  }

  if (( $+commands[$curl_command] )) || [[ "$curl_command" == */* && -x "$curl_command" ]]; then
    stage_dir="$(command mktemp -d "$cache_dir/.stage.XXXXXX")" || stage_dir=""
    if [[ -n "$stage_dir" ]]; then
      _plan_build_download "$base_url/plan_build.zsh" "$stage_dir/plan_build.zsh" &&
        _plan_build_download "$base_url/SKILL.md" "$stage_dir/SKILL.md" &&
        _plan_build_download "$base_url/ARCHITECT.md" "$stage_dir/ARCHITECT.md"
      refresh_rc=$?
      if (( interrupted_rc )); then
        _plan_build_cleanup
        trap - EXIT HUP INT TERM
        return "$interrupted_rc"
      fi
    else
      refresh_rc=1
    fi
    if (( refresh_rc == 0 )) &&
       _plan_build_validate_release "$stage_dir"; then
      release_dir="$(command mktemp -d "$cache_dir/release.XXXXXX")" || release_dir=""
      if [[ -n "$release_dir" ]] &&
         command rmdir "$release_dir" &&
         command mv "$stage_dir" "$release_dir" &&
         _plan_build_acquire_activation_lock; then
        stage_dir=""
        release_dir="${release_dir:A}"
        current_tmp="$(command mktemp "$cache_dir/.current.XXXXXX")" &&
          command rm -f "$current_tmp" &&
          command ln -s "$release_dir" "$current_tmp" || current_tmp=""

        if [[ -n "$current_tmp" && -L "$current_tmp" ]] &&
           _plan_build_install_skill_links &&
           _plan_build_replace_path "$current_tmp" "$cache_dir/current"; then
          current_tmp=""
          selected_release="$release_dir"
        fi
        _plan_build_release_activation_lock || true
      fi
    fi
  fi

  if (( interrupted_rc )); then
    _plan_build_cleanup
    trap - EXIT HUP INT TERM
    return "$interrupted_rc"
  fi

  if [[ -z "$selected_release" ]]; then
    if ! _plan_build_select_current; then
      if (( ! $+commands[$curl_command] )) && [[ ! ( "$curl_command" == */* && -x "$curl_command" ) ]]; then
        printf "Error: curl is required because no valid cached plan-build bundle is available.\n" >&2
      else
        printf "Error: Unable to refresh plan-build and no valid cached bundle is available.\n" >&2
      fi
      return 1
    fi
    if (( ! $+commands[$curl_command] )) && [[ ! ( "$curl_command" == */* && -x "$curl_command" ) ]]; then
      printf "Warning: curl is unavailable; using the validated cached plan-build bundle.\n" >&2
    else
      printf "Warning: Unable to refresh plan-build; using the validated cached bundle.\n" >&2
    fi
  fi

  if [[ "$(command readlink "$skill_file" 2>/dev/null)" != "$cache_dir/current/SKILL.md" ||
        "$(command readlink "$architect_file" 2>/dev/null)" != "$cache_dir/current/ARCHITECT.md" ]]; then
    if ! _plan_build_acquire_activation_lock || ! _plan_build_install_skill_links; then
      _plan_build_release_activation_lock 2>/dev/null || true
      if (( interrupted_rc )); then
        _plan_build_cleanup
        trap - EXIT HUP INT TERM
        return "$interrupted_rc"
      fi
      printf "Error: Unable to install the plan-build skill links.\n" >&2
      return 1
    fi
    _plan_build_release_activation_lock || true
  fi

  if (( interrupted_rc )); then
    _plan_build_cleanup
    trap - EXIT HUP INT TERM
    return "$interrupted_rc"
  fi

  PLAN_BUILD_SKILL_PATH="$selected_release/SKILL.md" \
  PLAN_BUILD_ARCHITECT_SKILL_PATH="$selected_release/ARCHITECT.md" \
    command zsh "$selected_release/plan_build.zsh" "$@" &
  active_pid=$!
  wait "$active_pid"
  call_rc=$?
  active_pid=""
  (( interrupted_rc )) && call_rc="$interrupted_rc"
  _plan_build_cleanup
  trap - EXIT HUP INT TERM
  return "$call_rc"
}

# -----------------------------------------------------------------------------
# Function: aicommit (Automated Conventional Commit Engine Wrapper)
# -----------------------------------------------------------------------------
aicommit() {
  local diff engine prompt
  
  # 1. Get diff safely: exclude lock files/minified files and cap at ~100k characters to prevent CLI crashes
  diff=$(git diff --cached -- . ":(exclude)*.lock" ":(exclude)*-lock.json" ":(exclude)*.min.js" | head -c 100000)
  
  if [ -z "$diff" ]; then
    printf "❌ Error: Nothing staged to commit.\n" >&2
    return 1
  fi

  if [ ! -f "$HOME/.config/ai-commit-prompt.txt" ]; then
    printf "❌ Error: Configuration file not found at ~/.config/ai-commit-prompt.txt\n" >&2
    printf "Please create it and paste your system prompt inside.\n" >&2
    return 1
  fi

  engine=${1:-claude}
  prompt=$(cat "$HOME/.config/ai-commit-prompt.txt")

  case "$engine" in
    claude)
      echo "🤖 Claude is analyzing staged changes..."
      cat "$HOME/.config/ai-commit-prompt.txt" <(echo -e "\n\nHere is the git diff:\n$diff") \
        | command claude --allowedTools 'Bash(git commit *)' --permission-mode dontAsk -p \
          "Read the provided instructions and diff, then generate and execute the commit."
      ;;

    codex)
      echo "🤖 Codex is analyzing staged changes..."
      cat "$HOME/.config/ai-commit-prompt.txt" <(echo -e "\n\nHere is the git diff:\n$diff") \
        | command codex --ask-for-approval never exec --sandbox workspace-write --ephemeral \
          "Read the provided instructions and diff, then generate and execute the commit."
      ;;

    copilot)
      echo "🤖 Copilot is analyzing staged changes..."
      copilot -p "$prompt

Here is the git diff:
$diff" -s --no-ask-user --allow-tool='shell(git:*)'
      ;;

    opencode)
      echo "🤖 OpenCode is analyzing staged changes..."
      cat "$HOME/.config/ai-commit-prompt.txt" <(echo -e "\n\nHere is the git diff:\n$diff") | opencode run
      ;;

    *)
      printf "❌ Error: Invalid engine '%s'\n" "$engine" >&2
      printf "Usage: aicommit [claude | codex | copilot | opencode]\n" >&2
      return 1
      ;;
  esac
}

# -----------------------------------------------------------------------------
# Function: create (Efficiently create file + parent dirs)
# -----------------------------------------------------------------------------
create() {
  if ! command -v install >/dev/null 2>&1; then
    printf "Error: 'install' coreutil is not available.\n" >&2
    return 1
  fi

  if [ $# -eq 0 ]; then
    printf "Usage: create <file> [file ...]\n" >&2
    return 2
  fi

  for p in "$@"; do
    # Expand tilde manually if shell doesn't
    [[ "$p" == "~/"* ]] && p="${HOME}/${p#\~/}"

    if [ -z "$p" ] || [ "$p" = "/" ]; then
      printf "create: refusing to operate on '%s'\n" "$p" >&2
      continue
    fi

    if [ -e "$p" ]; then
      printf "create: '%s' already exists. Skipping.\n" "$p" >&2
      continue
    fi

    if install -D /dev/null "$p"; then
      echo "Created '$p'"
    fi
  done
}

# -----------------------------------------------------------------------------
# Function: kill_port (Kill or check the process using a port)
# -----------------------------------------------------------------------------
kill_port() {
  local action="kill"
  local signal="TERM"
  local port
  local pids
  local pid

  case "${1:-}" in
    -c|--check)
      action="check"
      shift
      ;;
    -k|--kill)
      action="kill"
      shift
      ;;
    -f|--force)
      action="kill"
      signal="KILL"
      shift
      ;;
    -h|--help|"")
      printf "Usage: kill_port [--check|-c|--kill|-k|--force|-f] <port_number>\n" >&2
      return 1
      ;;
  esac

  port="${1:-}"
  if [[ ! "$port" =~ ^[0-9]+$ ]] || [ "$port" -lt 1 ] || [ "$port" -gt 65535 ]; then
    printf "Error: port must be a number between 1 and 65535.\n" >&2
    printf "Usage: kill_port [--check|-c|--kill|-k|--force|-f] <port_number>\n" >&2
    return 1
  fi

  if [[ "$OSTYPE" == "darwin"* ]]; then
    pids="$(
      {
        lsof -nP -tiTCP:"$port" -sTCP:LISTEN 2>/dev/null
        lsof -nP -tiUDP:"$port" 2>/dev/null
      } | sort -u
    )"

    if [ -z "$pids" ]; then
      printf "Port %s is FREE\n" "$port"
      return 0
    fi

    printf "Port %s is in use:\n" "$port"
    lsof -nP -iTCP:"$port" -sTCP:LISTEN -iUDP:"$port" 2>/dev/null
  else
    local port_hex
    local inodes

    port_hex="$(printf "%04X" "$port")"
    inodes="$(
      awk -v port="$port_hex" '
        NR > 1 {
          split($2, local_addr, ":")
          if (toupper(local_addr[length(local_addr)]) == port && ($4 == "0A" || FILENAME ~ /udp/)) {
            print $10
          }
        }
      ' /proc/net/tcp /proc/net/tcp6 /proc/net/udp /proc/net/udp6 2>/dev/null | sort -u
    )"

    if [ -z "$inodes" ]; then
      printf "Port %s is FREE\n" "$port"
      return 0
    fi

    pids=""
    pids="$(
      find /proc/[0-9]*/fd -maxdepth 1 -type l -printf "%p %l\n" 2>/dev/null |
        awk -v inodes="$inodes" '
          BEGIN {
            split(inodes, inode_list, " ")
            for (i in inode_list) {
              wanted["socket:[" inode_list[i] "]"] = 1
            }
          }
          $2 in wanted {
            split($1, path, "/")
            print path[3]
          }
        ' | sort -u
    )"

    if [ -z "$pids" ]; then
      printf "Port %s is in use, but no readable process owner was found.\n" "$port" >&2
      return 1
    fi

    printf "Port %s is in use:\n" "$port"
    for pid in $pids; do
      if [ -r "/proc/$pid/cmdline" ]; then
        printf "  PID %-8s %s\n" "$pid" "$(tr '\0' ' ' < "/proc/$pid/cmdline")"
      else
        printf "  PID %s\n" "$pid"
      fi
    done
  fi

  if [ "$action" = "kill" ]; then
    for pid in $pids; do
      if kill "-$signal" "$pid" 2>/dev/null; then
        printf "Killed PID %s with SIG%s.\n" "$pid" "$signal"
      else
        printf "Error: failed to kill PID %s. Try with sudo or --force.\n" "$pid" >&2
        return 1
      fi
    done
  fi
}

# -----------------------------------------------------------------------------
# Function: append_path (Adds to session PATH if exists)
# -----------------------------------------------------------------------------
append_path() {
    local dir="$1"
    if [ -d "$dir" ]; then
        case ":$PATH:" in
            *":$dir:"*) ;; 
            *) PATH="$PATH:$dir" ;;
        esac
    elif [ "${SUPPRESS_WARNINGS:-0}" -ne 1 ]; then
        echo "Warning: $dir does not exist." >&2
    fi
}

# -----------------------------------------------------------------------------
# Function: add_path_to_config (Fixed awk/sed injection)
# -----------------------------------------------------------------------------
add_path_to_config() {
  local new_path="$1"
  local config_file="$HOME/.bashrc"
  [[ "$SHELL" == *"zsh"* ]] && config_file="$HOME/.zshrc"

  if [ -z "$new_path" ]; then
    printf "Usage: add_path_to_config <directory>\n" >&2
    return 1
  fi

  new_path="${new_path/#\~/$HOME}"

  if [ ! -d "$new_path" ]; then
    printf "Warning: '%s' does not exist. Add anyway? (y/N) " "$new_path"
    read -r REPLY
    [[ ! $REPLY =~ ^[Yy]$ ]] && return 1
  fi

  # Check if already exists in file
  if grep -Fq "append_path \"$new_path\"" "$config_file"; then
    printf "Notice: Already in %s.\n" "$config_file"
    return 0
  fi

  # Robust Injection: Use sed to insert before export PATH or just append
  if grep -q "^export PATH" "$config_file"; then
    sed -i.bak "/^export PATH/i append_path \"$new_path\"" "$config_file"
  else
    echo "append_path \"$new_path\"" >> "$config_file"
    echo "export PATH" >> "$config_file"
  fi

  printf "✅ Success: Added to %s\n" "$config_file"
  append_path "$new_path" && export PATH
}
