feat: 接入 Pi 内置 codemode,并修复全面审查发现的问题

- codemode:Tool Search 常驻(alwaysEnabled)、权限 allow(嵌套调用仍逐个过权限门)、
  tools.jsonc 登记使用规则;RTK 跳过 parentToolCallId 嵌套调用,避免丢失 bash
  structuredContent;Tool Search 目录过滤 hidden / codemode(script-only)exposure;
  扩展加载测试加载 builtin:codemode 并断言其常驻激活
- 搜索 key 不再经命令行参数传递:search-auth.mjs 改为 --set-stdin(先读校验再加锁),
  configure.sh 交互输入经管道、非交互用 --<provider> -
- CodeGraph 客户端监听子进程 stdin error,避免 EPIPE 未处理导致崩溃
- 移除 PI_TOOL_SEARCH/HERMES_MEMORY/RTK_CONFIG_PATH 环境变量入口,测试改用工厂 configPath 注入
- pi-subagents 固定 vitest / coverage-istanbul 4.1.10,修复 npm ls 版本冲突
- 补 pi-web-search / pi-worktree UPSTREAM.md 与 pi-minimal-footer AGENTS.md,
  files 白名单补齐并加测试;.codegraph/.gitignore 移出跟踪
- detect_kitty 优先识别官方安装目录

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
云服务部-叶林立
2026-10-21 23:18:34 -07:00
co-authored by Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
parent 56cbc83296
commit f9a7f743dd
46 changed files with 585 additions and 198 deletions
+21 -13
View File
@@ -24,24 +24,25 @@ search_usage() {
cat <<'EOF'
用法:
./configure.sh search
./configure.sh search --tavily KEY --exa KEY --keenable KEY
./configure.sh search --tavily - 从标准输入读取 key
./configure.sh search --migrate [search.env 路径]
./configure.sh search --list
选项:
--tavily KEY 配置 tavily api_key 凭据
--exa KEY 配置 exa api_key 凭据
--keenable KEY 配置 keenable api_key 凭据
--tavily - 从标准输入读取 tavily api_key 凭据
--exa - 从标准输入读取 exa api_key 凭据
--keenable - 从标准输入读取 keenable api_key 凭据
--migrate 从旧 search.env 导入缺失的 key
--list 显示各 provider 配置状态(不输出 key)
--auth FILE 覆盖 auth.json 路径
-h, --help 显示帮助
不传 key 参数时进入隐藏输入的交互模式;传入任意 key 参数时不交互,
未指定的 provider 保留已有值。凭据写入 Pi 的 auth.json
($PI_CODING_AGENT_DIR/auth.json 或 ~/.pi/agent/auth.json,权限 600)。
key 支持 auth.json 原生语义:字面量、$ENV_VAR / ${ENV_VAR} 插值、
以及 !command(执行命令取 stdout,如 "!op read op://Vault/Tavily/key")。
key 不得出现在命令行参数中:非交互方式用 `--<provider> -` 从标准输入
读取,每次调用最多一个 provider 可经标准输入配置;不传参数时进入
隐藏输入的交互模式,未指定的 provider 保留已有值。凭据写入 Pi 的
auth.json($PI_CODING_AGENT_DIR/auth.json 或 ~/.pi/agent/auth.json,
权限 600)。key 支持 auth.json 原生语义:字面量、$ENV_VAR / ${ENV_VAR}
插值、以及 !command(执行命令取 stdout,如 "!op read op://Vault/Tavily/key")。
EOF
}
@@ -52,6 +53,7 @@ configure_search() {
SEARCH_AUTH_FILE=
search_mode=interactive
search_did_work=0
search_stdin_provider=
run_search_auth() {
if [ -n "$SEARCH_AUTH_FILE" ]; then
@@ -69,7 +71,7 @@ configure_search() {
prompt_label=$1
prompt_configured=$2
if [ ! -t 0 ]; then
warn "交互模式需要终端;请改用 --tavily/--exa/--keenable 参数。"
warn "交互模式需要终端;请改用 '--<provider> -' 从标准输入提供 key。"
return 2
fi
if [ "$prompt_configured" -eq 1 ]; then
@@ -88,9 +90,15 @@ configure_search() {
while [ "$#" -gt 0 ]; do
case $1 in
--tavily|--exa|--keenable)
[ "$#" -ge 2 ] || { warn "$1 缺少 KEY"; exit 2; }
[ "$#" -ge 2 ] || { warn "$1 缺少 KEY 或 -"; exit 2; }
if [ "$2" != "-" ]; then
warn "$1 不接受明文 key:key 不得出现在命令行参数中;请用交互模式或 '$1 -' 从标准输入提供。"
exit 2
fi
[ -z "$search_stdin_provider" ] || { warn "每次调用最多一个 provider 可经标准输入读取 key。"; exit 2; }
search_stdin_provider=${1#--}
search_mode=noninteractive; search_did_work=1
run_search_auth --set "${1#--}=$2" || exit $?
run_search_auth --set-stdin "$search_stdin_provider" || exit $?
shift 2 ;;
--migrate)
search_mode=noninteractive; search_did_work=1
@@ -121,7 +129,7 @@ configure_search() {
if search_has_key "$provider"; then configured=1; else configured=0; fi
value=$(search_prompt_key "$label" "$configured") || exit $?
if [ -n "$value" ]; then
run_search_auth --set "$provider=$value" || exit $?
printf '%s' "$value" | run_search_auth --set-stdin "$provider" || exit $?
search_did_work=1
fi
done