mirror of
https://bitbucket.org/siakitem/my-pi.git
synced 2026-08-28 08:35:57 +00:00
feat: add optional terminal environment setup
This commit is contained in:
@@ -19,8 +19,8 @@
|
|||||||
- `@ogulcancelik/pi-auto-permissions@0.1.3`:根据当前对话复核配置命中的 Bash 命令,不是全工具审批层。
|
- `@ogulcancelik/pi-auto-permissions@0.1.3`:根据当前对话复核配置命中的 Bash 命令,不是全工具审批层。
|
||||||
- `@ogulcancelik/pi-codex-compaction@0.1.3`:为 `openai-codex` 提供原生远程 compaction,默认阈值为 90%。
|
- `@ogulcancelik/pi-codex-compaction@0.1.3`:为 `openai-codex` 提供原生远程 compaction,默认阈值为 90%。
|
||||||
- 根包还固定安装 `pi-context-view`、`@firstpick/pi-extension-codex-fast-mode` 和 `@gotgenes/pi-permission-system`。
|
- 根包还固定安装 `pi-context-view`、`@firstpick/pi-extension-codex-fast-mode` 和 `@gotgenes/pi-permission-system`。
|
||||||
- `install.sh`:先安装根组合包,再交互检查 CodeGraph、Kotlin LSP、Java 21+ 和 JDT LS;缺失依赖只在用户明确选择 `Y` 后安装。
|
- `install.sh`:先安装根组合包,再交互检查 Kitty/Solarized Dark、Oh My Zsh/Powerlevel10k/Zsh 插件、CodeGraph、Kotlin LSP、Java 21+ 和 JDT LS;缺失项目只在用户明确选择 `Y` 后安装或配置。
|
||||||
- `uninstall.sh`:只移除根组合包,不卸载可能被其他项目共享的 CodeGraph、Kotlin LSP、JDT LS 或 Java。
|
- `uninstall.sh`:只移除根组合包,不卸载或还原可能被其他项目共享的终端环境、CodeGraph、Kotlin LSP、JDT LS 或 Java。
|
||||||
|
|
||||||
## 当前职责与默认行为
|
## 当前职责与默认行为
|
||||||
|
|
||||||
@@ -40,9 +40,10 @@
|
|||||||
- 当前只把 Git 非只读操作和包管理类 Bash 命令交给 `pi-auto-permissions` 根据用户上下文复核。低风险操作可自动允许;中风险操作仅在用户明确授权目标与约束时自动允许;高风险操作即使已有概括授权也必须回到用户确认。文件/系统/网络高风险操作继续由现有解析能力更强的 `pi-permission-system` 处理。
|
- 当前只把 Git 非只读操作和包管理类 Bash 命令交给 `pi-auto-permissions` 根据用户上下文复核。低风险操作可自动允许;中风险操作仅在用户明确授权目标与约束时自动允许;高风险操作即使已有概括授权也必须回到用户确认。文件/系统/网络高风险操作继续由现有解析能力更强的 `pi-permission-system` 处理。
|
||||||
- 将 Auto Permissions 规则配置为 `.*` 最多只能复核所有 Bash 命令,不能覆盖其他工具,并会为普通 Bash 调用增加额外模型请求、延迟和成本。若未来目标是让现有所有 `ask` 先经模型裁决,必须另行实现 `pi-permission-system` authorizer 集成,不能仅靠该 npm 包配置实现。
|
- 将 Auto Permissions 规则配置为 `.*` 最多只能复核所有 Bash 命令,不能覆盖其他工具,并会为普通 Bash 调用增加额外模型请求、延迟和成本。若未来目标是让现有所有 `ask` 先经模型裁决,必须另行实现 `pi-permission-system` authorizer 集成,不能仅靠该 npm 包配置实现。
|
||||||
- `pi-lsp` 使用组合包部署的 `kotlin-lsp --stdio` 与 `jdtls` 配置,但根包安装本身不安装这两个系统可执行文件;便捷脚本可在用户逐项明确确认后通过 Homebrew 安装 Kotlin LSP、Java 21 和 JDT LS。
|
- `pi-lsp` 使用组合包部署的 `kotlin-lsp --stdio` 与 `jdtls` 配置,但根包安装本身不安装这两个系统可执行文件;便捷脚本可在用户逐项明确确认后通过 Homebrew 安装 Kotlin LSP、Java 21 和 JDT LS。
|
||||||
|
- 终端环境配置只属于便捷脚本:Kitty 可选安装后可通过官方 kitten 启用 Solarized Dark;Oh My Zsh 使用不覆盖 `.zshrc`、不切换 shell 的 unattended 安装;Powerlevel10k 默认部署官方 Lean/ASCII 预设以跳过首次向导;`git`、`zsh-autosuggestions`、`zsh-syntax-highlighting` 逐项询问后才安装或启用。修改 `.zshrc` 前必须创建带时间戳的备份。
|
||||||
- Codex 远程压缩只对 `openai-codex` 生效,默认在 turn boundary 达到 90% 时触发;Hermes Memory 默认使用 policy-only 模式。
|
- Codex 远程压缩只对 `openai-codex` 生效,默认在 turn boundary 达到 90% 时触发;Hermes Memory 默认使用 policy-only 模式。
|
||||||
- `install.sh` 默认从 `git:git@bitbucket.org:siakitem/my-pi.git` 安装,并允许用 `PI_PACKAGE_SOURCE` 覆盖来源;组合包安装失败时立即停止,机器级依赖安装失败时继续检查其余依赖并最终返回非零状态。
|
- `install.sh` 默认从 `git:git@bitbucket.org:siakitem/my-pi.git` 安装,并允许用 `PI_PACKAGE_SOURCE` 覆盖来源;组合包安装失败时立即停止,机器级依赖安装失败时继续检查其余依赖并最终返回非零状态。
|
||||||
- CodeGraph 的可选安装使用官方远程安装脚本;Kotlin LSP、Java 21 和 JDT LS 的可选安装使用 Homebrew。没有 Homebrew 时保留已经完成的组合包安装并报告依赖安装失败。
|
- CodeGraph 的可选安装使用官方远程安装脚本;macOS Kitty 使用 Homebrew cask,其他系统使用 Kitty 官方安装器;Kotlin LSP、Java 21 和 JDT LS 使用 Homebrew;Oh My Zsh 使用官方安装器,Powerlevel10k 与两个第三方 Zsh 插件从各自官方 Git 仓库克隆。缺少 Homebrew、curl 或 git 时保留已经完成的组合包安装并报告失败。
|
||||||
- `install.sh` 不检查默认不需要的 `rtk` CLI;`uninstall.sh` 使用同一个 `PI_PACKAGE_SOURCE` 规则调用 `pi remove`,且不删除共享机器级工具。
|
- `install.sh` 不检查默认不需要的 `rtk` CLI;`uninstall.sh` 使用同一个 `PI_PACKAGE_SOURCE` 规则调用 `pi remove`,且不删除共享机器级工具。
|
||||||
|
|
||||||
## 修改边界
|
## 修改边界
|
||||||
@@ -55,7 +56,7 @@
|
|||||||
- Pi 核心包只作为宿主 peer dependencies,不得在组合包内再安装或打包一套 Pi runtime;保留根 `.npmrc` 的 peer 安装策略。
|
- Pi 核心包只作为宿主 peer dependencies,不得在组合包内再安装或打包一套 Pi runtime;保留根 `.npmrc` 的 peer 安装策略。
|
||||||
- 上游仅作为参考来源。同步上游改动时先核对本仓库已有修改,再按明确范围移植;不要直接覆盖本地实现。
|
- 上游仅作为参考来源。同步上游改动时先核对本仓库已有修改,再按明确范围移植;不要直接覆盖本地实现。
|
||||||
- `install.sh` 和 `uninstall.sh` 必须保持 POSIX `sh` 兼容和可执行权限,并包含在根 `package.json` 的 `files` 中;修改脚本行为时同步更新 README 和本文件。
|
- `install.sh` 和 `uninstall.sh` 必须保持 POSIX `sh` 兼容和可执行权限,并包含在根 `package.json` 的 `files` 中;修改脚本行为时同步更新 README 和本文件。
|
||||||
- 机器级依赖安装必须保持逐项询问且默认拒绝,不得在没有用户明确确认的情况下自动安装;卸载不得顺带删除共享机器级工具。
|
- 机器级依赖和用户终端配置必须保持逐项询问且默认拒绝,不得在没有用户明确确认的情况下自动安装或改写;`.zshrc` 修改必须保留备份,卸载不得顺带删除或还原共享工具和用户终端配置。
|
||||||
- 未经明确要求,不执行发布、提交、推送、运行安装/卸载脚本或安装到用户 Pi 运行目录等外部写操作。
|
- 未经明确要求,不执行发布、提交、推送、运行安装/卸载脚本或安装到用户 Pi 运行目录等外部写操作。
|
||||||
|
|
||||||
## `pi-rtk-optimizer` 开发约定
|
## `pi-rtk-optimizer` 开发约定
|
||||||
@@ -72,7 +73,7 @@
|
|||||||
|
|
||||||
组合包依赖或加载入口变化时,至少验证根 `npm install` 幂等、锁文件有效,以及全部扩展可在隔离的临时 Pi agent 目录加载。权限配置变化时使用当前固定版本的 `pi-permission-system` schema 校验,并验证包装入口部署后的文件与仓库源配置一致。
|
组合包依赖或加载入口变化时,至少验证根 `npm install` 幂等、锁文件有效,以及全部扩展可在隔离的临时 Pi agent 目录加载。权限配置变化时使用当前固定版本的 `pi-permission-system` schema 校验,并验证包装入口部署后的文件与仓库源配置一致。
|
||||||
|
|
||||||
安装或卸载脚本变化时,至少运行 `sh -n install.sh`、`sh -n uninstall.sh` 和 ShellCheck,并核对脚本仍具有可执行权限、仍包含在根 `package.json` 的 `files` 中、README 描述与实际流程一致。涉及真实 `pi install`、`pi remove`、Homebrew 或远程 CodeGraph 安装器的端到端验证属于外部写操作,未经明确要求不得执行。
|
安装或卸载脚本变化时,至少运行 `sh -n install.sh`、`sh -n uninstall.sh` 和 ShellCheck,并核对脚本仍具有可执行权限、仍包含在根 `package.json` 的 `files` 中、README 描述与实际流程一致。涉及真实 `pi install`、`pi remove`、Homebrew、远程 Kitty/Oh My Zsh 安装器、Git 克隆或真实用户终端配置的端到端验证属于外部写操作,未经明确要求不得执行;可以使用隔离的临时 HOME 和 mock 命令验证分支行为。
|
||||||
|
|
||||||
在 `pi-rtk-optimizer/` 内按改动范围选择最小充分验证:
|
在 `pi-rtk-optimizer/` 内按改动范围选择最小充分验证:
|
||||||
|
|
||||||
|
|||||||
@@ -28,9 +28,24 @@
|
|||||||
pi install git:git@bitbucket.org:siakitem/my-pi.git
|
pi install git:git@bitbucket.org:siakitem/my-pi.git
|
||||||
```
|
```
|
||||||
|
|
||||||
安装组合包成功后,脚本会检查 `codegraph`、`kotlin-lsp`、Java 21+ 和 `jdtls`。缺失的
|
安装组合包成功后,脚本会依次检查终端环境和机器级 CLI。所有缺失项目都逐项显示
|
||||||
依赖会逐项显示 `[y/N]` 选项,仅在用户明确选择 `Y` 后安装。Kotlin、Java 和 JDT LS 的
|
`[y/N]`,默认拒绝,仅在用户明确选择 `Y` 后修改机器或用户配置:
|
||||||
自动安装使用 Homebrew;如果机器没有 Homebrew,脚本会保留组合包安装结果并给出提示。
|
|
||||||
|
- 检查 Kitty;macOS 使用 Homebrew cask 安装,其他系统使用 Kitty 官方安装器。Kitty
|
||||||
|
可用后继续检查并可通过官方 `themes` kitten 配置 `Solarized Dark`。
|
||||||
|
- 检查 Oh My Zsh。安装采用官方 unattended 模式,不切换默认 shell、不立即启动 Zsh,
|
||||||
|
也不覆盖现有 `.zshrc`。
|
||||||
|
- 检查 Powerlevel10k;可克隆到 Oh My Zsh 的 custom themes 目录,并在没有现有
|
||||||
|
`~/.p10k.zsh` 时复制官方 Lean 预设、切换为兼容性更高的 ASCII 图标模式。脚本会把
|
||||||
|
`ZSH_THEME` 和预设加载语句写入 `.zshrc`,因此首次启动不会进入交互配置向导。
|
||||||
|
- 逐项检查 `git`、`zsh-autosuggestions` 和 `zsh-syntax-highlighting` 是否已经在
|
||||||
|
`.zshrc` 的 `plugins` 数组中启用。后两个插件缺少源码时会先克隆到 Oh My Zsh 的
|
||||||
|
custom plugins 目录;语法高亮按最后一个插件处理。
|
||||||
|
- 最后继续检查 `codegraph`、`kotlin-lsp`、Java 21+ 和 `jdtls`。Kotlin、Java 和 JDT LS
|
||||||
|
的自动安装使用 Homebrew。
|
||||||
|
|
||||||
|
脚本首次改动 `.zshrc` 前会在同目录创建带时间戳的备份。若机器没有所需的 Homebrew、
|
||||||
|
`curl` 或 `git`,脚本会保留已完成的安装结果、继续检查其他项目,并最终返回非零状态。
|
||||||
`rtk` 只供默认关闭的命令改写使用,因此不会作为必装依赖检查。
|
`rtk` 只供默认关闭的命令改写使用,因此不会作为必装依赖检查。
|
||||||
|
|
||||||
也可以绕过脚本,直接运行上面的 `pi install` 命令,此时机器级 CLI 不会被检查。
|
也可以绕过脚本,直接运行上面的 `pi install` 命令,此时机器级 CLI 不会被检查。
|
||||||
@@ -41,8 +56,9 @@ pi install git:git@bitbucket.org:siakitem/my-pi.git
|
|||||||
./uninstall.sh
|
./uninstall.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
卸载脚本只调用 `pi remove`,不会删除 CodeGraph、Kotlin LSP、JDT LS 或 Java,因为这些
|
卸载脚本只调用 `pi remove`,不会删除 Kitty、终端主题、Oh My Zsh、Powerlevel10k、Zsh
|
||||||
机器级工具可能仍被其他项目使用。两个脚本都可通过 `PI_PACKAGE_SOURCE` 覆盖默认包源,
|
插件、CodeGraph、Kotlin LSP、JDT LS 或 Java,因为这些用户环境或机器级工具可能仍被其他
|
||||||
|
项目使用。两个脚本都可通过 `PI_PACKAGE_SOURCE` 覆盖默认包源,
|
||||||
例如在本地检出中测试:
|
例如在本地检出中测试:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
+319
-5
@@ -4,7 +4,13 @@ set -u
|
|||||||
|
|
||||||
PACKAGE_SOURCE=${PI_PACKAGE_SOURCE:-git:git@bitbucket.org:siakitem/my-pi.git}
|
PACKAGE_SOURCE=${PI_PACKAGE_SOURCE:-git:git@bitbucket.org:siakitem/my-pi.git}
|
||||||
CODEGRAPH_INSTALL_URL=https://raw.githubusercontent.com/colbymchenry/codegraph/main/install.sh
|
CODEGRAPH_INSTALL_URL=https://raw.githubusercontent.com/colbymchenry/codegraph/main/install.sh
|
||||||
|
KITTY_INSTALL_URL=https://sw.kovidgoyal.net/kitty/installer.sh
|
||||||
|
OH_MY_ZSH_INSTALL_URL=https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh
|
||||||
|
POWERLEVEL10K_REPOSITORY=https://github.com/romkatv/powerlevel10k.git
|
||||||
|
ZSH_AUTOSUGGESTIONS_REPOSITORY=https://github.com/zsh-users/zsh-autosuggestions.git
|
||||||
|
ZSH_SYNTAX_HIGHLIGHTING_REPOSITORY=https://github.com/zsh-users/zsh-syntax-highlighting.git
|
||||||
install_failed=0
|
install_failed=0
|
||||||
|
zshrc_backup_done=0
|
||||||
|
|
||||||
say() {
|
say() {
|
||||||
printf '%s\n' "$*"
|
printf '%s\n' "$*"
|
||||||
@@ -14,9 +20,9 @@ warn() {
|
|||||||
printf '警告: %s\n' "$*" >&2
|
printf '警告: %s\n' "$*" >&2
|
||||||
}
|
}
|
||||||
|
|
||||||
ask_to_install() {
|
ask_yes_no() {
|
||||||
dependency=$1
|
prompt=$1
|
||||||
printf '未检测到 %s。是否现在安装?[y/N] ' "$dependency"
|
printf '%s [y/N] ' "$prompt"
|
||||||
if ! IFS= read -r answer; then
|
if ! IFS= read -r answer; then
|
||||||
answer=n
|
answer=n
|
||||||
fi
|
fi
|
||||||
@@ -26,6 +32,14 @@ ask_to_install() {
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ask_to_install() {
|
||||||
|
ask_yes_no "未检测到 $1。是否现在安装?"
|
||||||
|
}
|
||||||
|
|
||||||
|
ask_to_enable() {
|
||||||
|
ask_yes_no "尚未启用 $1。是否现在安装所需文件并启用?"
|
||||||
|
}
|
||||||
|
|
||||||
require_brew() {
|
require_brew() {
|
||||||
if command -v brew >/dev/null 2>&1; then
|
if command -v brew >/dev/null 2>&1; then
|
||||||
return 0
|
return 0
|
||||||
@@ -93,6 +107,246 @@ install_jdtls() {
|
|||||||
command -v jdtls >/dev/null 2>&1
|
command -v jdtls >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
install_kitty() {
|
||||||
|
case $(uname -s) in
|
||||||
|
Darwin)
|
||||||
|
require_brew || return 1
|
||||||
|
brew install --cask kitty || return 1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if ! command -v curl >/dev/null 2>&1; then
|
||||||
|
warn "安装 Kitty 需要 curl。"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
curl -L "$KITTY_INSTALL_URL" | sh /dev/stdin || return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
detect_kitty
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve_kitty_config_dir() {
|
||||||
|
kitty_config_dir=${KITTY_CONFIG_DIRECTORY:-${XDG_CONFIG_HOME:-$HOME/.config}/kitty}
|
||||||
|
}
|
||||||
|
|
||||||
|
kitty_solarized_dark_configured() {
|
||||||
|
resolve_kitty_config_dir
|
||||||
|
[ -f "$kitty_config_dir/current-theme.conf" ] || return 1
|
||||||
|
[ -f "$kitty_config_dir/kitty.conf" ] || return 1
|
||||||
|
grep -F "Solarized Dark" "$kitty_config_dir/current-theme.conf" >/dev/null 2>&1 || return 1
|
||||||
|
grep -E '^[[:space:]]*include[[:space:]]+([^#[:space:]]*/)?current-theme\.conf([[:space:]]*(#.*)?)?$' \
|
||||||
|
"$kitty_config_dir/kitty.conf" >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
configure_kitty_solarized_dark() {
|
||||||
|
"$kitty_bin" +kitten themes --reload-in=none "Solarized Dark"
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
oh_my_zsh_installed() {
|
||||||
|
resolve_zsh_paths
|
||||||
|
[ -f "$oh_my_zsh_dir/oh-my-zsh.sh" ]
|
||||||
|
}
|
||||||
|
|
||||||
|
install_oh_my_zsh() {
|
||||||
|
if ! command -v curl >/dev/null 2>&1; then
|
||||||
|
warn "安装 Oh My Zsh 需要 curl。"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if ! command -v git >/dev/null 2>&1; then
|
||||||
|
warn "安装 Oh My Zsh 需要 git。"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
resolve_zsh_paths
|
||||||
|
oh_my_zsh_installer=$(curl -fsSL "$OH_MY_ZSH_INSTALL_URL") || return 1
|
||||||
|
RUNZSH=no CHSH=no KEEP_ZSHRC=yes ZSH="$oh_my_zsh_dir" \
|
||||||
|
sh -c "$oh_my_zsh_installer" "" --unattended --keep-zshrc || return 1
|
||||||
|
oh_my_zsh_installed
|
||||||
|
}
|
||||||
|
|
||||||
|
prepare_zshrc() {
|
||||||
|
resolve_zsh_paths
|
||||||
|
zshrc_dir=${zshrc_file%/*}
|
||||||
|
[ "$zshrc_dir" = "$zshrc_file" ] && zshrc_dir=.
|
||||||
|
mkdir -p "$zshrc_dir" || return 1
|
||||||
|
if [ ! -f "$zshrc_file" ]; then
|
||||||
|
: > "$zshrc_file" || return 1
|
||||||
|
fi
|
||||||
|
if [ "$zshrc_backup_done" -eq 0 ]; then
|
||||||
|
zshrc_backup="$zshrc_file.my-pi-backup-$(date +%Y%m%d%H%M%S)"
|
||||||
|
cp "$zshrc_file" "$zshrc_backup" || return 1
|
||||||
|
zshrc_backup_done=1
|
||||||
|
say "已备份现有 Zsh 配置到 $zshrc_backup"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
zshrc_has_oh_my_zsh_loader() {
|
||||||
|
[ -f "$zshrc_file" ] || return 1
|
||||||
|
grep -E '^[[:space:]]*(source|\.)[[:space:]].*oh-my-zsh\.sh' "$zshrc_file" >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_oh_my_zsh_loader() {
|
||||||
|
prepare_zshrc || return 1
|
||||||
|
if zshrc_has_oh_my_zsh_loader; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
{
|
||||||
|
printf '\n# Oh My Zsh (managed by my-pi install.sh)\n'
|
||||||
|
printf 'export ZSH="%s"\n' "$oh_my_zsh_dir"
|
||||||
|
printf '%s\n' "source \"\$ZSH/oh-my-zsh.sh\""
|
||||||
|
} >> "$zshrc_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
set_powerlevel10k_theme() {
|
||||||
|
prepare_zshrc || return 1
|
||||||
|
tmp_file=$(mktemp "${TMPDIR:-/tmp}/my-pi-zshrc.XXXXXX") || return 1
|
||||||
|
if ! awk '
|
||||||
|
BEGIN { inserted = 0 }
|
||||||
|
/^[[:space:]]*ZSH_THEME[[:space:]]*=/ { next }
|
||||||
|
!inserted && /^[[:space:]]*(source|\.)[[:space:]].*oh-my-zsh\.sh/ {
|
||||||
|
print "ZSH_THEME=\"powerlevel10k/powerlevel10k\""
|
||||||
|
inserted = 1
|
||||||
|
}
|
||||||
|
{ print }
|
||||||
|
END {
|
||||||
|
if (!inserted) print "ZSH_THEME=\"powerlevel10k/powerlevel10k\""
|
||||||
|
}
|
||||||
|
' "$zshrc_file" > "$tmp_file"; then
|
||||||
|
rm -f "$tmp_file"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
cp "$tmp_file" "$zshrc_file" || {
|
||||||
|
rm -f "$tmp_file"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
rm -f "$tmp_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
p10k_config_sourced() {
|
||||||
|
[ -f "$zshrc_file" ] || return 1
|
||||||
|
grep -E '^[[:space:]]*\[\[[[:space:]].*\.p10k\.zsh.*source[[:space:]].*\.p10k\.zsh' \
|
||||||
|
"$zshrc_file" >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_p10k_config_source() {
|
||||||
|
if p10k_config_sourced; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
printf '\n# Powerlevel10k preset (managed by my-pi install.sh)\n[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh\n' \
|
||||||
|
>> "$zshrc_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
configure_powerlevel10k() {
|
||||||
|
resolve_zsh_paths
|
||||||
|
powerlevel10k_dir=$zsh_custom_dir/themes/powerlevel10k
|
||||||
|
if [ ! -f "$powerlevel10k_dir/powerlevel10k.zsh-theme" ]; then
|
||||||
|
if ! command -v git >/dev/null 2>&1; then
|
||||||
|
warn "安装 Powerlevel10k 需要 git。"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
mkdir -p "$zsh_custom_dir/themes" || return 1
|
||||||
|
git clone --depth=1 "$POWERLEVEL10K_REPOSITORY" "$powerlevel10k_dir" || return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$HOME/.p10k.zsh" ]; then
|
||||||
|
sed 's/POWERLEVEL9K_MODE=nerdfont-complete/POWERLEVEL9K_MODE=ascii/' \
|
||||||
|
"$powerlevel10k_dir/config/p10k-lean.zsh" > "$HOME/.p10k.zsh" || return 1
|
||||||
|
say "已写入 Powerlevel10k Lean/ASCII 预设,首次启动不会进入配置向导。"
|
||||||
|
fi
|
||||||
|
set_powerlevel10k_theme || return 1
|
||||||
|
ensure_oh_my_zsh_loader || return 1
|
||||||
|
ensure_p10k_config_source
|
||||||
|
}
|
||||||
|
|
||||||
|
zsh_plugin_enabled() {
|
||||||
|
plugin=$1
|
||||||
|
[ -f "$zshrc_file" ] || return 1
|
||||||
|
awk -v target="$plugin" '
|
||||||
|
{
|
||||||
|
line = $0
|
||||||
|
sub(/[[:space:]]*#.*/, "", line)
|
||||||
|
if (line ~ /^[[:space:]]*plugins[[:space:]]*[+]?=/) active = 1
|
||||||
|
if (active) {
|
||||||
|
gsub(/[()=+]/, " ", line)
|
||||||
|
count = split(line, fields, /[[:space:]]+/)
|
||||||
|
for (i = 1; i <= count; i++) if (fields[i] == target) found = 1
|
||||||
|
if ($0 ~ /\)/) active = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END { exit(found ? 0 : 1) }
|
||||||
|
' "$zshrc_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
add_zsh_plugin() {
|
||||||
|
plugin=$1
|
||||||
|
prepare_zshrc || return 1
|
||||||
|
ensure_oh_my_zsh_loader || return 1
|
||||||
|
tmp_file=$(mktemp "${TMPDIR:-/tmp}/my-pi-zshrc.XXXXXX") || return 1
|
||||||
|
if ! awk -v plugin="$plugin" '
|
||||||
|
BEGIN { added = 0 }
|
||||||
|
!added && /^[[:space:]]*(source|\.)[[:space:]].*oh-my-zsh\.sh/ {
|
||||||
|
print "plugins+=(" plugin ")"
|
||||||
|
added = 1
|
||||||
|
}
|
||||||
|
{ print }
|
||||||
|
END { if (!added) print "plugins+=(" plugin ")" }
|
||||||
|
' "$zshrc_file" > "$tmp_file"; then
|
||||||
|
rm -f "$tmp_file"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
cp "$tmp_file" "$zshrc_file" || {
|
||||||
|
rm -f "$tmp_file"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
rm -f "$tmp_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
install_and_enable_zsh_plugin() {
|
||||||
|
plugin=$1
|
||||||
|
repository=${2:-}
|
||||||
|
if [ -n "$repository" ] && [ ! -d "$zsh_custom_dir/plugins/$plugin" ]; then
|
||||||
|
if ! command -v git >/dev/null 2>&1; then
|
||||||
|
warn "安装 $plugin 需要 git。"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
mkdir -p "$zsh_custom_dir/plugins" || return 1
|
||||||
|
git clone --depth=1 "$repository" "$zsh_custom_dir/plugins/$plugin" || return 1
|
||||||
|
fi
|
||||||
|
add_zsh_plugin "$plugin"
|
||||||
|
}
|
||||||
|
|
||||||
|
check_zsh_plugin() {
|
||||||
|
plugin=$1
|
||||||
|
description=$2
|
||||||
|
repository=${3:-}
|
||||||
|
if zsh_plugin_enabled "$plugin"; then
|
||||||
|
say "✓ $plugin 已启用"
|
||||||
|
elif ask_to_enable "$description"; then
|
||||||
|
install_and_enable_zsh_plugin "$plugin" "$repository" || record_install_failure "$plugin"
|
||||||
|
else
|
||||||
|
say "- 已跳过 ${plugin}。"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
if ! command -v pi >/dev/null 2>&1; then
|
if ! command -v pi >/dev/null 2>&1; then
|
||||||
warn "找不到 pi,无法安装组合包。请先安装 Pi 并确保 pi 位于 PATH。"
|
warn "找不到 pi,无法安装组合包。请先安装 Pi 并确保 pi 位于 PATH。"
|
||||||
exit 127
|
exit 127
|
||||||
@@ -104,7 +358,67 @@ if ! pi install "$PACKAGE_SOURCE"; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
say "Pi 组合包安装完成,开始检查机器级 CLI 依赖。"
|
say "Pi 组合包安装完成,开始检查终端环境和机器级 CLI 依赖。"
|
||||||
|
|
||||||
|
kitty_ok=0
|
||||||
|
if detect_kitty; then
|
||||||
|
kitty_ok=1
|
||||||
|
say "✓ Kitty 已安装(${kitty_bin})"
|
||||||
|
elif ask_to_install "Kitty 终端"; then
|
||||||
|
if install_kitty; then
|
||||||
|
kitty_ok=1
|
||||||
|
say "✓ Kitty 安装完成"
|
||||||
|
else
|
||||||
|
record_install_failure "Kitty"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
say "- 已跳过 Kitty;不会检查 Solarized Dark 主题。"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$kitty_ok" -eq 1 ]; then
|
||||||
|
if kitty_solarized_dark_configured; then
|
||||||
|
say "✓ Kitty 已配置 Solarized Dark"
|
||||||
|
elif ask_yes_no "Kitty 尚未配置 Solarized Dark。是否现在配置?"; then
|
||||||
|
configure_kitty_solarized_dark || record_install_failure "Kitty Solarized Dark 主题"
|
||||||
|
else
|
||||||
|
say "- 已跳过 Kitty Solarized Dark 主题。"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
oh_my_zsh_ok=0
|
||||||
|
if oh_my_zsh_installed; then
|
||||||
|
oh_my_zsh_ok=1
|
||||||
|
say "✓ Oh My Zsh 已安装(${oh_my_zsh_dir})"
|
||||||
|
elif ask_to_install "Oh My Zsh"; then
|
||||||
|
if install_oh_my_zsh; then
|
||||||
|
oh_my_zsh_ok=1
|
||||||
|
say "✓ Oh My Zsh 安装完成"
|
||||||
|
else
|
||||||
|
record_install_failure "Oh My Zsh"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
say "- 已跳过 Oh My Zsh;不会检查 Powerlevel10k 和 Zsh 插件。"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$oh_my_zsh_ok" -eq 1 ]; then
|
||||||
|
resolve_zsh_paths
|
||||||
|
powerlevel10k_dir=$zsh_custom_dir/themes/powerlevel10k
|
||||||
|
if [ -f "$powerlevel10k_dir/powerlevel10k.zsh-theme" ] && \
|
||||||
|
grep -E "^[[:space:]]*ZSH_THEME[[:space:]]*=[[:space:]]*[\"']?powerlevel10k/powerlevel10k[\"']?" \
|
||||||
|
"$zshrc_file" >/dev/null 2>&1 && [ -f "$HOME/.p10k.zsh" ] && p10k_config_sourced; then
|
||||||
|
say "✓ Powerlevel10k 已安装并配置"
|
||||||
|
elif ask_yes_no "Powerlevel10k 尚未完整配置。是否安装并应用免向导的 Lean/ASCII 预设?"; then
|
||||||
|
configure_powerlevel10k || record_install_failure "Powerlevel10k"
|
||||||
|
else
|
||||||
|
say "- 已跳过 Powerlevel10k。"
|
||||||
|
fi
|
||||||
|
|
||||||
|
check_zsh_plugin "git" "git 插件" ""
|
||||||
|
check_zsh_plugin "zsh-autosuggestions" "zsh-autosuggestions(命令自动建议)" \
|
||||||
|
"$ZSH_AUTOSUGGESTIONS_REPOSITORY"
|
||||||
|
check_zsh_plugin "zsh-syntax-highlighting" "zsh-syntax-highlighting(语法高亮)" \
|
||||||
|
"$ZSH_SYNTAX_HIGHLIGHTING_REPOSITORY"
|
||||||
|
fi
|
||||||
|
|
||||||
if command -v codegraph >/dev/null 2>&1; then
|
if command -v codegraph >/dev/null 2>&1; then
|
||||||
say "✓ codegraph 已安装"
|
say "✓ codegraph 已安装"
|
||||||
@@ -151,5 +465,5 @@ else
|
|||||||
say "- 已跳过 jdtls;Java LSP 功能将不可用。"
|
say "- 已跳过 jdtls;Java LSP 功能将不可用。"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
say "依赖检查完成。RTK 命令改写默认关闭,因此未检查可选的 rtk CLI。"
|
say "终端环境与依赖检查完成。RTK 命令改写默认关闭,因此未检查可选的 rtk CLI。"
|
||||||
exit "$install_failed"
|
exit "$install_failed"
|
||||||
|
|||||||
Reference in New Issue
Block a user