#!/bin/bash # omarchy:summary=Store, read, or delete AI provider API keys # omarchy:args= # omarchy:examples=omarchycn ai secret set deepseek | omarchycn ai secret get deepseek set -euo pipefail action="${1:?usage: omarchycn ai secret }" provider="${2:?usage: omarchycn ai secret }" if [[ ! $provider =~ ^[a-z0-9-]+$ ]]; then echo "Invalid provider name: $provider" >&2 exit 1 fi FILE_DIR="$HOME/.local/state/omarchycn/secrets" FILE_PATH="$FILE_DIR/$provider" secret_service_ok() { omarchy-cmd-present secret-tool && secret-tool search service omarchycn > /dev/null 2>&1 } pass_ok() { omarchy-cmd-present pass && pass ls > /dev/null 2>&1 } case "$action" in set) if [[ -t 0 ]]; then read -rs -p "API key for $provider: " key echo else IFS= read -r key || true fi if [[ -z $key ]]; then echo "Empty key refused" >&2 exit 1 fi if secret_service_ok; then printf '%s' "$key" | secret-tool store --label "OmarchyCN AI: $provider" service omarchycn key "ai/$provider" # Purge stale copies in lower-priority backends so get never falls # through to an outdated key; a failed purge fails the set. # Existence check is decryption-free (store file on disk). if pass_ok && [[ -f ${PASSWORD_STORE_DIR:-$HOME/.password-store}/omarchycn/ai/$provider.gpg ]]; then if ! pass rm -f "omarchycn/ai/$provider" > /dev/null; then echo "存储成功但 pass 中的旧副本清除失败,请手动执行: pass rm omarchycn/ai/$provider" >&2 exit 1 fi fi rm -f "$FILE_PATH" echo "Stored in Secret Service (secret-tool)" elif pass_ok; then printf '%s\n' "$key" | pass insert -m -f "omarchycn/ai/$provider" > /dev/null rm -f "$FILE_PATH" echo "Stored in pass (omarchycn/ai/$provider)" else mkdir -p "$FILE_DIR" chmod 700 "$FILE_DIR" rm -f "$FILE_PATH" (umask 177 && printf '%s' "$key" > "$FILE_PATH") echo "Stored in $FILE_PATH (0600 file fallback — 安装 libsecret 或 pass 可获得更安全的存储)" fi ;; get) if secret_service_ok && secret-tool lookup service omarchycn key "ai/$provider" 2>/dev/null; then exit 0 fi if pass_ok && pass show "omarchycn/ai/$provider" 2>/dev/null; then exit 0 fi if [[ -f $FILE_PATH ]]; then cat "$FILE_PATH" exit 0 fi echo "No secret stored for $provider (run: omarchycn ai secret set $provider)" >&2 exit 1 ;; rm) removed=0 if secret_service_ok && secret-tool clear service omarchycn key "ai/$provider" 2>/dev/null; then removed=1 fi if pass_ok && pass rm -f "omarchycn/ai/$provider" > /dev/null 2>&1; then removed=1 fi if [[ -f $FILE_PATH ]]; then rm -f "$FILE_PATH" removed=1 fi if omarchy-cmd-present secret-tool && ! secret_service_ok; then echo "Secret Service 不可达,无法确认其中的副本已清除;服务恢复后重新执行 rm" >&2 exit 1 fi if (( removed == 0 )); then echo "No secret stored for $provider" >&2 exit 1 fi echo "Secret for $provider removed" ;; *) echo "Unknown action: $action (expected set, get, or rm)" >&2 exit 1 ;; esac