Import claude-code-switcher from the Windows build
Source of truth so far has been c:\Users\smoido\projects\cli on the Windows box, which has no git history of its own. This is that tree copied verbatim over SSH, minus dist/ - the PowerShell build, the POSIX port under linux/, and the presets both share. Recorded as its own commit so that everything after it is a reviewable diff rather than an undifferentiated first drop.
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env bash
|
||||
# Secret storage for claude-mode (POSIX port), sourced by claude-mode and by the
|
||||
# key helper.
|
||||
#
|
||||
# Windows uses DPAPI, which binds ciphertext to one Windows user on one machine.
|
||||
# There is no single equivalent here, so this picks the best available backend:
|
||||
#
|
||||
# macOS security login Keychain, unlocked with the session
|
||||
# Linux secret-tool libsecret / GNOME Keyring, same idea
|
||||
# Linux pass gpg-backed, agent-cached
|
||||
# any file 0600 in ~/.claude-mode/vault - PLAINTEXT
|
||||
#
|
||||
# The file backend is the honest fallback: it is no worse than the API keys
|
||||
# people already keep in .bashrc, but it is not encrypted and claude-mode says so
|
||||
# out loud rather than implying protection it does not provide.
|
||||
|
||||
CM_VAULT_DIR="${CM_ROOT:-$HOME/.claude-mode}/vault"
|
||||
CM_VAULT_SERVICE="claude-mode"
|
||||
|
||||
cm_vault_backend() {
|
||||
if [ -n "${CLAUDE_MODE_VAULT:-}" ]; then printf '%s\n' "$CLAUDE_MODE_VAULT"; return; fi
|
||||
if [ "$(uname -s)" = "Darwin" ] && command -v security >/dev/null 2>&1; then
|
||||
printf 'security\n'; return
|
||||
fi
|
||||
if command -v secret-tool >/dev/null 2>&1; then printf 'secret-tool\n'; return; fi
|
||||
if command -v pass >/dev/null 2>&1; then printf 'pass\n'; return; fi
|
||||
printf 'file\n'
|
||||
}
|
||||
|
||||
cm_vault_backend_label() {
|
||||
case "$(cm_vault_backend)" in
|
||||
security) printf 'macOS Keychain\n' ;;
|
||||
secret-tool) printf 'libsecret (GNOME Keyring)\n' ;;
|
||||
pass) printf 'pass (gpg)\n' ;;
|
||||
file) printf 'plain file, 0600 (NOT encrypted)\n' ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# cm_vault_set <ref> - reads the secret from stdin
|
||||
cm_vault_set() {
|
||||
local ref="$1" secret
|
||||
IFS= read -r secret || true
|
||||
[ -n "$secret" ] || { echo "empty key, aborted" >&2; return 1; }
|
||||
|
||||
case "$(cm_vault_backend)" in
|
||||
security)
|
||||
security add-generic-password -U -a "$ref" -s "$CM_VAULT_SERVICE" -w "$secret" >/dev/null
|
||||
;;
|
||||
secret-tool)
|
||||
printf '%s' "$secret" | secret-tool store --label="claude-mode $ref" \
|
||||
service "$CM_VAULT_SERVICE" ref "$ref" >/dev/null
|
||||
;;
|
||||
pass)
|
||||
printf '%s\n' "$secret" | pass insert -m -f "$CM_VAULT_SERVICE/$ref" >/dev/null
|
||||
;;
|
||||
file)
|
||||
mkdir -p "$CM_VAULT_DIR"
|
||||
chmod 700 "$CM_VAULT_DIR" 2>/dev/null || true
|
||||
local f="$CM_VAULT_DIR/$ref.key"
|
||||
( umask 077; printf '%s' "$secret" > "$f" )
|
||||
chmod 600 "$f" 2>/dev/null || true
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# cm_vault_get <ref> - prints the secret, or nothing (exit 1) if absent
|
||||
cm_vault_get() {
|
||||
local ref="$1" out=""
|
||||
case "$(cm_vault_backend)" in
|
||||
security)
|
||||
out="$(security find-generic-password -a "$ref" -s "$CM_VAULT_SERVICE" -w 2>/dev/null)" || return 1
|
||||
;;
|
||||
secret-tool)
|
||||
out="$(secret-tool lookup service "$CM_VAULT_SERVICE" ref "$ref" 2>/dev/null)" || return 1
|
||||
;;
|
||||
pass)
|
||||
out="$(pass show "$CM_VAULT_SERVICE/$ref" 2>/dev/null | head -n1)" || return 1
|
||||
;;
|
||||
file)
|
||||
[ -f "$CM_VAULT_DIR/$ref.key" ] || return 1
|
||||
out="$(cat "$CM_VAULT_DIR/$ref.key")"
|
||||
;;
|
||||
esac
|
||||
[ -n "$out" ] || return 1
|
||||
printf '%s' "$out"
|
||||
}
|
||||
|
||||
cm_vault_has() { cm_vault_get "$1" >/dev/null 2>&1; }
|
||||
|
||||
cm_vault_mask() {
|
||||
local k="$1"
|
||||
if [ -z "$k" ]; then printf '(none)\n'; return; fi
|
||||
if [ "${#k}" -le 12 ]; then printf '****\n'; return; fi
|
||||
printf '%s...%s\n' "${k:0:8}" "${k: -4}"
|
||||
}
|
||||
Reference in New Issue
Block a user