mirror of
https://github.com/HKUDS/CLI-Anything.git
synced 2026-09-18 23:42:43 +08:00
7154ed7fa5
Ship a first-class Cursor adaptation (commands, skill, rules, marketplace manifest, CI installer tests) and document generator vs Hub consumer install paths in README/README_CN. Co-authored-by: Cursor <cursoragent@cursor.com>
103 lines
3.1 KiB
Bash
103 lines
3.1 KiB
Bash
# Shared helpers for CLI-Anything Cursor plugin install/uninstall (bash).
|
|
# shellcheck shell=bash
|
|
|
|
normalize_path_key() {
|
|
printf '%s' "${1}" | tr '[:upper:]' '[:lower:]' | tr '\\' '/' | sed 's:/*$::'
|
|
}
|
|
|
|
# Convert Git Bash / MSYS / Cygwin / WSL-style paths to Windows host paths for Cursor tools.
|
|
to_host_path() {
|
|
local p="${1}"
|
|
if command -v cygpath >/dev/null 2>&1; then
|
|
cygpath -w "${p}"
|
|
return 0
|
|
fi
|
|
case "$(uname -s 2>/dev/null || true)" in
|
|
MINGW*|MSYS*|CYGWIN*|Linux)
|
|
if [[ "${p}" =~ ^/([a-zA-Z])/(.*)$ ]]; then
|
|
local drive rest
|
|
drive="$(printf '%s' "${BASH_REMATCH[1]}" | tr '[:lower:]' '[:upper:]')"
|
|
rest="${BASH_REMATCH[2]//\//\\}"
|
|
printf '%s:\\%s' "${drive}" "${rest}"
|
|
return 0
|
|
fi
|
|
if [[ "${p}" =~ ^/mnt/([a-zA-Z])/(.*)$ ]]; then
|
|
local drive rest
|
|
drive="$(printf '%s' "${BASH_REMATCH[1]}" | tr '[:lower:]' '[:upper:]')"
|
|
rest="${BASH_REMATCH[2]//\//\\}"
|
|
printf '%s:\\%s' "${drive}" "${rest}"
|
|
return 0
|
|
fi
|
|
;;
|
|
esac
|
|
printf '%s' "${p}"
|
|
}
|
|
|
|
# Resolve CURSOR_PLUGINS_HOME / default plugins root.
|
|
# Second arg: "create" to mkdir (install), anything else skips creating.
|
|
resolve_plugins_home() {
|
|
local raw="${1}"
|
|
local mode="${2:-}"
|
|
if [[ -z "${raw}" || "${raw}" == "." || "${raw}" == ".." ]]; then
|
|
echo "Invalid CURSOR_PLUGINS_HOME: ${raw}" >&2
|
|
return 1
|
|
fi
|
|
|
|
# Canonicalize without creating the path (abspath collapses ".." safely).
|
|
if command -v python3 >/dev/null 2>&1; then
|
|
raw="$(python3 -c 'import os,sys; print(os.path.abspath(os.path.expanduser(sys.argv[1])))' "${raw}")"
|
|
elif command -v python >/dev/null 2>&1; then
|
|
raw="$(python -c 'import os,sys; print(os.path.abspath(os.path.expanduser(sys.argv[1])))' "${raw}")"
|
|
else
|
|
if [[ "${raw}" == "~"* ]]; then
|
|
raw="${HOME}${raw:1}"
|
|
fi
|
|
if [[ "${raw}" != /* && "${raw}" != [A-Za-z]:* && "${raw}" != \\* ]]; then
|
|
raw="$(pwd)/${raw}"
|
|
fi
|
|
case "${raw}" in
|
|
*..*)
|
|
echo "Invalid CURSOR_PLUGINS_HOME (refuses '..' without python): ${raw}" >&2
|
|
return 1
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
if [[ "$(basename "${raw}")" != "plugins" ]]; then
|
|
echo "CURSOR_PLUGINS_HOME must resolve to a directory named 'plugins' (got: ${raw})" >&2
|
|
echo "Example: ~/.cursor/plugins or /custom/path/plugins" >&2
|
|
return 1
|
|
fi
|
|
|
|
if [[ "${mode}" == "create" ]]; then
|
|
mkdir -p "${raw}"
|
|
if command -v realpath >/dev/null 2>&1; then
|
|
raw="$(realpath "${raw}")"
|
|
else
|
|
raw="$(cd "${raw}" && pwd -P)"
|
|
fi
|
|
elif [[ -d "${raw}" ]]; then
|
|
if command -v realpath >/dev/null 2>&1; then
|
|
raw="$(realpath "${raw}")"
|
|
else
|
|
raw="$(cd "${raw}" && pwd -P)"
|
|
fi
|
|
fi
|
|
printf '%s' "${raw}"
|
|
}
|
|
|
|
# True when path is .../local/cli-anything (slash or backslash).
|
|
is_cli_anything_install_path() {
|
|
local key
|
|
key="$(normalize_path_key "${1}")"
|
|
[[ "$(basename "${key}")" == "cli-anything" ]] || return 1
|
|
case "${key}" in
|
|
*/local/cli-anything) return 0 ;;
|
|
*) return 1 ;;
|
|
esac
|
|
}
|
|
|
|
discovery_pointer_path() {
|
|
printf '%s' "${HOME}/.cursor/cli-anything-generator.root"
|
|
}
|