Files
my-pi/search_config.sh
T
云服务部-叶林立andDevin <158243242+devin-ai-integration[bot]@users.noreply.github.com> 0c9823ef5c feat(pi-web-search): 搜索凭据迁移到 Pi auth.json
三个搜索 key 改为 auth.json 中的 tavily/exa/keenable api_key 凭据,
pi-web-search/auth.ts 复刻上游 resolve-config-value 语义(!command、
$VAR 插值、credential env 优先、$$/$! 转义)并在每次调用时读取,
进程环境变量与 search.env 不再被直接读取。search_config.sh 重写为
scripts/search-auth.mjs 的薄封装:加锁原子写、权限 600、保留其他
凭据条目,支持 --migrate 从旧 search.env 一次性导入。

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

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-19 20:39:13 -07:00

120 lines
3.1 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/sh
set -u
say() {
printf '%s\n' "$*"
}
warn() {
printf '错误: %s\n' "$*" >&2
}
usage() {
cat <<'EOF'
用法:
./search_config.sh
./search_config.sh --tavily KEY --exa KEY --keenable KEY
./search_config.sh --migrate [search.env 路径]
./search_config.sh --list
选项:
--tavily KEY 配置 tavily api_key 凭据
--exa KEY 配置 exa api_key 凭据
--keenable KEY 配置 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")。
EOF
}
SCRIPT_DIR=$(cd -- "$(dirname -- "$0")" && pwd)
AUTH_MJS="$SCRIPT_DIR/scripts/search-auth.mjs"
[ -f "$AUTH_MJS" ] || { warn "找不到 ${AUTH_MJS}"; exit 1; }
AUTH_FILE=
mode=interactive
did_work=0
run_auth() {
if [ -n "$AUTH_FILE" ]; then
node "$AUTH_MJS" --auth "$AUTH_FILE" "$@"
else
node "$AUTH_MJS" "$@"
fi
}
has_key() {
run_auth --has "$1" >/dev/null 2>&1
}
prompt_key() {
prompt_label=$1
prompt_configured=$2
if [ ! -t 0 ]; then
warn "交互模式需要终端;请改用 --tavily/--exa/--keenable 参数。"
return 2
fi
if [ "$prompt_configured" -eq 1 ]; then
printf '%s API key(回车保留现有值): ' "$prompt_label" >&2
else
printf '%s API key(回车跳过): ' "$prompt_label" >&2
fi
stty -echo
IFS= read -r prompt_value || prompt_status=$?
stty echo
printf '\n' >&2
[ "${prompt_status:-0}" -eq 0 ] || return "$prompt_status"
printf '%s\n' "$prompt_value"
}
while [ "$#" -gt 0 ]; do
case $1 in
--tavily|--exa|--keenable)
[ "$#" -ge 2 ] || { warn "$1 缺少 KEY"; exit 2; }
mode=noninteractive; did_work=1
run_auth --set "${1#--}=$2" || exit $?
shift 2 ;;
--migrate)
mode=noninteractive; did_work=1
if [ "$#" -ge 2 ] && [ "${2#--}" = "$2" ]; then
run_auth --migrate "$2" || exit $?
shift 2
else
run_auth --migrate || exit $?
shift
fi
say "如确认 auth.json 可用,可手动删除旧 search.env 文件。" ;;
--list) mode=noninteractive; did_work=1; run_auth --list || exit $?; shift ;;
--auth)
[ "$#" -ge 2 ] || { warn "--auth 缺少 FILE"; exit 2; }
AUTH_FILE=$2; shift 2 ;;
-h|--help) usage; exit 0 ;;
*) warn "未知参数:$1"; usage >&2; exit 2 ;;
esac
done
if [ "$mode" = interactive ]; then
for provider in tavily exa keenable; do
case $provider in
tavily) label=Tavily ;;
exa) label=Exa ;;
keenable) label=Keenable ;;
esac
if has_key "$provider"; then configured=1; else configured=0; fi
value=$(prompt_key "$label" "$configured") || exit $?
if [ -n "$value" ]; then
run_auth --set "$provider=$value" || exit $?
did_work=1
fi
done
[ "$did_work" -eq 1 ] || say "未提供任何 key,auth.json 保持不变。"
fi