mirror of
https://bitbucket.org/siakitem/my-pi.git
synced 2026-10-26 10:45:22 +00:00
配置统一:权限策略、硬防御、Tool Search、提示词封面以及新迁入的 RTK、pi-compaction、pi-worktree、pi-hermes-memory 配置全部由扩展 直接读取已安装组合包内的 config/,pi install / pi update 即完成部署; 删除 rebuild-bundle-config.mjs 与 bundle-manifest.json,my-pi/ 只保留 日志与缓存。update.sh 成功升级后将默认 git 来源的已安装副本 reset 回发布版本。AGENTS.md 新增「组合包配置原则」。 脚本整合:search_config.sh / ssh_config.sh 合并为 configure.sh search|ssh;install.sh / update.sh 共享函数抽到 scripts/lib.sh,远程 安装器改为先下载到临时文件再执行,下载失败可被检测。 权限:hard-guards 新增 protectedWrites,写入 Pi 凭据/设置、已安装 组合包与扩展目录、pi-ssh 凭据库时一律人工确认(跳过 AutoReview、 yolo 与 Session grant,无 UI 时拒绝);放行 ls、LSP 查询、ctx 只读、 web_search、Chrome 只读与 git 只读命令,skill_manage 改为 ask。 Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
204 lines
5.4 KiB
Bash
204 lines
5.4 KiB
Bash
#!/bin/sh
|
|
# Variables assigned here are consumed by the sourcing install.sh/update.sh.
|
|
# shellcheck disable=SC2034
|
|
|
|
# Shared helpers for the bundle's POSIX sh scripts.
|
|
# Source this file; it defines say(), warn(), the Kitty/Zsh resolution
|
|
# helpers, and the my-pi managed-block machinery used by install.sh and
|
|
# update.sh.
|
|
|
|
say() {
|
|
printf '%s\n' "$*"
|
|
}
|
|
|
|
warn() {
|
|
printf '警告: %s\n' "$*" >&2
|
|
}
|
|
|
|
detect_kitty() {
|
|
kitty_bin=
|
|
if command -v kitty >/dev/null 2>&1; then
|
|
kitty_bin=$(command -v kitty)
|
|
return 0
|
|
fi
|
|
for candidate in /Applications/kitty.app/Contents/MacOS/kitty "$HOME/.local/kitty.app/bin/kitty"; do
|
|
if [ -x "$candidate" ]; then
|
|
kitty_bin=$candidate
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
resolve_kitty_config_dir() {
|
|
kitty_config_dir=${KITTY_CONFIG_DIRECTORY:-${XDG_CONFIG_HOME:-$HOME/.config}/kitty}
|
|
}
|
|
|
|
resolve_zsh_paths() {
|
|
oh_my_zsh_dir=${ZSH:-$HOME/.oh-my-zsh}
|
|
zsh_custom_dir=${ZSH_CUSTOM:-$oh_my_zsh_dir/custom}
|
|
zshrc_file=${ZDOTDIR:-$HOME}/.zshrc
|
|
my_pi_config_dir=${XDG_CONFIG_HOME:-$HOME/.config}/my-pi
|
|
p10k_managed_config_file=$my_pi_config_dir/p10k.zsh
|
|
}
|
|
|
|
# Anchor regex shared by every "before the Oh My Zsh loader" managed block.
|
|
MY_PI_ZSH_LOADER_ANCHOR='^(# >>> my-pi:oh-my-zsh-loader >>>|[[:space:]]*(source|\.)[[:space:]].*oh-my-zsh\.sh)'
|
|
|
|
replace_zsh_managed_block() {
|
|
managed_id=$1
|
|
managed_placement=$2
|
|
managed_anchor=$3
|
|
shift 3
|
|
managed_content=$(mktemp "${TMPDIR:-/tmp}/my-pi-zsh-block.XXXXXX") || return 1
|
|
printf '%s\n' "$@" > "$managed_content"
|
|
my_pi_replace_managed_block "$zshrc_file" "$managed_id" "$managed_content" \
|
|
"$managed_placement" "$managed_anchor"
|
|
managed_status=$?
|
|
rm -f "$managed_content"
|
|
return "$managed_status"
|
|
}
|
|
|
|
MY_PI_MANAGED_BACKUPS=${MY_PI_MANAGED_BACKUPS:-}
|
|
|
|
my_pi_backup_once() {
|
|
managed_file=$1
|
|
case "|$MY_PI_MANAGED_BACKUPS|" in
|
|
*"|$managed_file|"*) return 0 ;;
|
|
esac
|
|
|
|
if [ -f "$managed_file" ]; then
|
|
managed_backup=$(mktemp "$managed_file.my-pi-backup-$(date +%Y%m%d%H%M%S).XXXXXX") || return 1
|
|
cp "$managed_file" "$managed_backup" || {
|
|
rm -f "$managed_backup"
|
|
return 1
|
|
}
|
|
say "已备份配置到 $managed_backup"
|
|
fi
|
|
MY_PI_MANAGED_BACKUPS=${MY_PI_MANAGED_BACKUPS:+$MY_PI_MANAGED_BACKUPS|}$managed_file
|
|
}
|
|
|
|
my_pi_managed_block_exists() {
|
|
managed_file=$1
|
|
managed_id=$2
|
|
managed_begin="# >>> my-pi:$managed_id >>>"
|
|
managed_end="# <<< my-pi:$managed_id <<<"
|
|
[ -f "$managed_file" ] || return 1
|
|
grep -F -x "$managed_begin" "$managed_file" >/dev/null 2>&1 &&
|
|
grep -F -x "$managed_end" "$managed_file" >/dev/null 2>&1
|
|
}
|
|
|
|
my_pi_replace_managed_block() {
|
|
managed_file=$1
|
|
managed_id=$2
|
|
managed_content_file=$3
|
|
managed_placement=${4:-append}
|
|
managed_anchor=${5:-}
|
|
managed_begin="# >>> my-pi:$managed_id >>>"
|
|
managed_end="# <<< my-pi:$managed_id <<<"
|
|
managed_dir=${managed_file%/*}
|
|
[ "$managed_dir" = "$managed_file" ] && managed_dir=.
|
|
mkdir -p "$managed_dir" || return 1
|
|
[ -f "$managed_file" ] || : > "$managed_file" || return 1
|
|
|
|
managed_counts=$(awk -v begin="$managed_begin" -v end="$managed_end" '
|
|
$0 == begin {
|
|
begins++
|
|
if (active) invalid = 1
|
|
active = 1
|
|
}
|
|
$0 == end {
|
|
ends++
|
|
if (!active) invalid = 1
|
|
active = 0
|
|
}
|
|
END {
|
|
if (active) invalid = 1
|
|
printf "%d %d %d\n", begins, ends, invalid
|
|
}
|
|
' "$managed_file") || return 1
|
|
managed_begin_count=${managed_counts%% *}
|
|
managed_remainder=${managed_counts#* }
|
|
managed_end_count=${managed_remainder%% *}
|
|
managed_invalid=${managed_remainder#* }
|
|
if [ "$managed_begin_count" -ne "$managed_end_count" ] || \
|
|
[ "$managed_begin_count" -gt 1 ] || [ "$managed_invalid" -ne 0 ]; then
|
|
warn "$managed_file 中的 my-pi:$managed_id 受管标记不完整或重复,已拒绝修改。"
|
|
return 1
|
|
fi
|
|
|
|
managed_tmp=$(mktemp "$managed_dir/.my-pi-managed.XXXXXX") || return 1
|
|
if ! awk \
|
|
-v begin="$managed_begin" \
|
|
-v end="$managed_end" \
|
|
-v content="$managed_content_file" \
|
|
-v placement="$managed_placement" \
|
|
-v anchor="$managed_anchor" '
|
|
function emit_block( line) {
|
|
print begin
|
|
while ((getline line < content) > 0) print line
|
|
close(content)
|
|
print end
|
|
}
|
|
BEGIN { replacing = 0; emitted = 0 }
|
|
$0 == begin {
|
|
emit_block()
|
|
replacing = 1
|
|
emitted = 1
|
|
next
|
|
}
|
|
replacing && $0 == end { replacing = 0; next }
|
|
replacing { next }
|
|
!emitted && placement == "before" && anchor != "" && $0 ~ anchor {
|
|
emit_block()
|
|
emitted = 1
|
|
}
|
|
{ print }
|
|
END {
|
|
if (!emitted) {
|
|
if (NR > 0) print ""
|
|
emit_block()
|
|
}
|
|
}
|
|
' "$managed_file" > "$managed_tmp"; then
|
|
rm -f "$managed_tmp"
|
|
return 1
|
|
fi
|
|
|
|
if cmp -s "$managed_tmp" "$managed_file"; then
|
|
rm -f "$managed_tmp"
|
|
return 0
|
|
fi
|
|
my_pi_backup_once "$managed_file" || {
|
|
rm -f "$managed_tmp"
|
|
return 1
|
|
}
|
|
if ! mv "$managed_tmp" "$managed_file"; then
|
|
rm -f "$managed_tmp"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
my_pi_sync_managed_file() {
|
|
managed_source=$1
|
|
managed_target=$2
|
|
[ -f "$managed_source" ] || {
|
|
warn "找不到仓库配置:$managed_source"
|
|
return 1
|
|
}
|
|
if [ -f "$managed_target" ] && cmp -s "$managed_source" "$managed_target"; then
|
|
return 0
|
|
fi
|
|
|
|
managed_target_dir=${managed_target%/*}
|
|
[ "$managed_target_dir" = "$managed_target" ] && managed_target_dir=.
|
|
mkdir -p "$managed_target_dir" || return 1
|
|
my_pi_backup_once "$managed_target" || return 1
|
|
managed_tmp=$(mktemp "$managed_target_dir/.my-pi-sync.XXXXXX") || return 1
|
|
if ! cp "$managed_source" "$managed_tmp" || ! mv "$managed_tmp" "$managed_target"; then
|
|
rm -f "$managed_tmp"
|
|
return 1
|
|
fi
|
|
say "已同步受管配置:$managed_target"
|
|
}
|