mirror of
https://wget.la/https://github.com/leookun/cursor-byok
synced 2026-08-17 19:47:10 +08:00
143 lines
4.1 KiB
Bash
Executable File
143 lines
4.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# extract.sh 从 Cursor 安装目录安全提取 Proto 文件。
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
INSTALLED_CURSOR_DEFAULT="/Applications/Cursor.app"
|
|
INPUT_DEFAULT="$INSTALLED_CURSOR_DEFAULT"
|
|
OUTPUT_DEFAULT="$PROJECT_DIR/proto"
|
|
|
|
INPUT_ROOT="${1:-$INPUT_DEFAULT}"
|
|
OUTPUT_DIR="${2:-$OUTPUT_DEFAULT}"
|
|
|
|
canonicalize_path() {
|
|
local path="$1"
|
|
local parent
|
|
local base
|
|
if [[ -d "$path" ]]; then
|
|
(cd "$path" && pwd -P)
|
|
return
|
|
fi
|
|
parent="$(dirname "$path")"
|
|
base="$(basename "$path")"
|
|
if [[ ! -d "$parent" ]]; then
|
|
echo "Parent directory does not exist: $parent" >&2
|
|
return 1
|
|
fi
|
|
printf '%s/%s\n' "$(cd "$parent" && pwd -P)" "$base"
|
|
}
|
|
|
|
# 文件输入只提取自身;目录输入扫描工作台、扩展宿主和扩展产物。
|
|
INPUT_PATHS=()
|
|
|
|
add_input() {
|
|
local candidate="$1"
|
|
local existing
|
|
if [[ ! -f "$candidate" ]]; then
|
|
return 0
|
|
fi
|
|
for existing in "${INPUT_PATHS[@]-}"; do
|
|
[[ "$existing" == "$candidate" ]] && return
|
|
done
|
|
INPUT_PATHS+=("$candidate")
|
|
}
|
|
|
|
if [[ -f "$INPUT_ROOT" ]]; then
|
|
add_input "$INPUT_ROOT"
|
|
elif [[ -d "$INPUT_ROOT" ]]; then
|
|
CANDIDATES=(
|
|
"$INPUT_ROOT/Contents/Resources/app/out/vs/workbench/workbench.desktop.main.js"
|
|
"$INPUT_ROOT/Resources/app/out/vs/workbench/workbench.desktop.main.js"
|
|
"$INPUT_ROOT/out/vs/workbench/workbench.desktop.main.js"
|
|
"$INPUT_ROOT/workbench.desktop.main.js"
|
|
"$INPUT_ROOT/Contents/Resources/app/out/vs/workbench/api/node/extensionHostProcess.js"
|
|
"$INPUT_ROOT/Resources/app/out/vs/workbench/api/node/extensionHostProcess.js"
|
|
"$INPUT_ROOT/out/vs/workbench/api/node/extensionHostProcess.js"
|
|
"$INPUT_ROOT/extensionHostProcess.js"
|
|
"$INPUT_ROOT/Contents/Resources/app/extensions/cursor-always-local/dist/main.js"
|
|
"$INPUT_ROOT/Resources/app/extensions/cursor-always-local/dist/main.js"
|
|
"$INPUT_ROOT/extensions/cursor-always-local/dist/main.js"
|
|
"$INPUT_ROOT/cursor-always-local/dist/main.js"
|
|
)
|
|
for CANDIDATE in "${CANDIDATES[@]}"; do
|
|
add_input "$CANDIDATE"
|
|
done
|
|
while IFS= read -r JS_FILE; do
|
|
add_input "$JS_FILE"
|
|
done < <(find "$INPUT_ROOT" -type f ! -path "*/node_modules/*" \( -name "workbench.desktop.main.js" -o -name "extensionHostProcess.js" -o -path "*/extensions/*/dist/main.js" \) | sort)
|
|
fi
|
|
|
|
if [[ -z "${INPUT_PATHS[*]-}" ]]; then
|
|
echo "No supported Cursor JS bundle found under: $INPUT_ROOT" >&2
|
|
echo "Install/update Cursor, or pass an explicit input bundle:" >&2
|
|
echo " $0 /path/to/Cursor.app [output-dir]" >&2
|
|
exit 1
|
|
fi
|
|
|
|
for INDEX in "${!INPUT_PATHS[@]}"; do
|
|
INPUT_PATHS[$INDEX]="$(canonicalize_path "${INPUT_PATHS[$INDEX]}")"
|
|
done
|
|
OUTPUT_DIR="$(canonicalize_path "$OUTPUT_DIR")"
|
|
CURRENT_DIR="$(pwd -P)"
|
|
|
|
case "$OUTPUT_DIR" in
|
|
"/"|"$HOME"|"$PROJECT_DIR"|"$SCRIPT_DIR"|"$CURRENT_DIR")
|
|
echo "Refusing unsafe output directory: $OUTPUT_DIR" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
for INPUT_PATH in "${INPUT_PATHS[@]}"; do
|
|
case "$INPUT_PATH" in
|
|
"$OUTPUT_DIR"|"$OUTPUT_DIR"/*)
|
|
echo "Refusing output directory that contains an input bundle: $OUTPUT_DIR" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
OUTPUT_PARENT="$(dirname "$OUTPUT_DIR")"
|
|
OUTPUT_BASENAME="$(basename "$OUTPUT_DIR")"
|
|
TEMP_DIR="$(mktemp -d "$OUTPUT_PARENT/.${OUTPUT_BASENAME}.tmp.XXXXXX")"
|
|
BACKUP_DIR=""
|
|
|
|
cleanup() {
|
|
if [[ -n "$TEMP_DIR" && -d "$TEMP_DIR" ]]; then
|
|
rm -rf "$TEMP_DIR"
|
|
fi
|
|
if [[ -n "$BACKUP_DIR" && -e "$BACKUP_DIR" ]]; then
|
|
if [[ ! -e "$OUTPUT_DIR" ]]; then
|
|
mv "$BACKUP_DIR" "$OUTPUT_DIR"
|
|
else
|
|
rm -rf "$BACKUP_DIR"
|
|
fi
|
|
fi
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
EXTRACT_ARGS=()
|
|
for INPUT_PATH in "${INPUT_PATHS[@]}"; do
|
|
EXTRACT_ARGS+=( -input "$INPUT_PATH" )
|
|
done
|
|
|
|
(
|
|
cd "$PROJECT_DIR"
|
|
go run ./extractor \
|
|
"${EXTRACT_ARGS[@]}" \
|
|
-output "$TEMP_DIR" \
|
|
-skip-format \
|
|
-strict
|
|
)
|
|
|
|
if [[ -e "$OUTPUT_DIR" ]]; then
|
|
BACKUP_DIR="$(mktemp -d "$OUTPUT_PARENT/.${OUTPUT_BASENAME}.backup.XXXXXX")"
|
|
rmdir "$BACKUP_DIR"
|
|
mv "$OUTPUT_DIR" "$BACKUP_DIR"
|
|
fi
|
|
mv "$TEMP_DIR" "$OUTPUT_DIR"
|
|
TEMP_DIR=""
|
|
if [[ -n "$BACKUP_DIR" ]]; then
|
|
rm -rf "$BACKUP_DIR"
|
|
BACKUP_DIR=""
|
|
fi
|