123 lines
3.9 KiB
Nix
123 lines
3.9 KiB
Nix
{ config, ... }:
|
|
|
|
let
|
|
envTpl = "${config.xdg.configHome}/op-env/env.tpl";
|
|
envCache = "${config.xdg.cacheHome}/op-env/env.fish";
|
|
in
|
|
{
|
|
# ── 1Password env template ──────────────────────────
|
|
# op:// references only — no real secrets, safe to commit
|
|
# Kept outside ~/.config/op — that dir must be 700 and owned by op CLI
|
|
xdg.configFile."op-env/env.tpl".text = ''
|
|
set -gx AI_GATEWAY_BASE_URL "{{ op://Developer/AI Gateway API/URL }}"
|
|
set -gx AI_GATEWAY_API_KEY "{{ op://Developer/AI Gateway API/credential }}"
|
|
set -gx EXA_API_KEY "{{ op://Developer/Exa API/credential }}"
|
|
set -gx CONTEXT7_API_KEY "{{ op://Developer/Context7 API/credential }}"
|
|
'';
|
|
|
|
programs.fish = {
|
|
enable = true;
|
|
|
|
shellAbbrs = {
|
|
# Navigation (one-shot, no need to recall in history)
|
|
".." = "cd ..";
|
|
"..." = "cd ../..";
|
|
};
|
|
|
|
shellAliases = {
|
|
# File listing (eza) — base aliases (ls/la/lt) from programs.eza
|
|
ll = "eza -lh";
|
|
lla = "eza -lah --time-style=long-iso";
|
|
|
|
cat = "bat --paging=never";
|
|
rm = "gomi";
|
|
lg = "lazygit";
|
|
};
|
|
|
|
interactiveShellInit = ''
|
|
set -g fish_greeting
|
|
fish_add_path $HOME/go/bin $HOME/.bun/bin
|
|
|
|
# Sudo: double Escape to prepend sudo
|
|
bind \e\e 'fish_commandline_prepend sudo'
|
|
|
|
# WSL clipboard
|
|
if set -q WSL_DISTRO_NAME
|
|
alias pbcopy clip.exe
|
|
alias pbpaste "powershell.exe -noprofile -c Get-Clipboard"
|
|
end
|
|
|
|
# 1Password → env vars (cached locally, no network on shell start)
|
|
# Startup only sources the cache; run op-env-refresh manually to fetch/update.
|
|
# Auth via OP_SERVICE_ACCOUNT_TOKEN (set it in ~/.config/fish/local.fish)
|
|
function op-env-refresh --description "Fetch secrets from 1Password and cache locally"
|
|
if not type -q op
|
|
echo "op-env: op CLI not found in PATH" >&2
|
|
return 1
|
|
end
|
|
if not set -q OP_SERVICE_ACCOUNT_TOKEN; or test -z "$OP_SERVICE_ACCOUNT_TOKEN"
|
|
echo "op-env: OP_SERVICE_ACCOUNT_TOKEN is not set" >&2
|
|
return 1
|
|
end
|
|
if not test -f "${envTpl}"
|
|
echo "op-env: template not found: ${envTpl}" >&2
|
|
return 1
|
|
end
|
|
set -l cache_dir (path dirname "${envCache}")
|
|
if not mkdir -p "$cache_dir"; or not chmod 700 "$cache_dir"
|
|
echo "op-env: cannot prepare cache dir: $cache_dir" >&2
|
|
return 1
|
|
end
|
|
set -l tmp (mktemp "$cache_dir/.tmp.XXXXXX")
|
|
or begin
|
|
echo "op-env: mktemp failed" >&2
|
|
return 1
|
|
end
|
|
if not op inject --in-file "${envTpl}" > "$tmp"
|
|
command rm -f "$tmp"
|
|
echo "op-env: inject failed; old cache kept" >&2
|
|
return 1
|
|
end
|
|
# Capture old var names before replacing cache
|
|
set -l old_vars
|
|
if test -f "${envCache}"
|
|
set old_vars (string match -rg 'set -gx (\S+)' < "${envCache}")
|
|
end
|
|
if not mv "$tmp" "${envCache}"
|
|
command rm -f "$tmp"
|
|
echo "op-env: cannot replace cache file" >&2
|
|
return 1
|
|
end
|
|
for var in $old_vars
|
|
set -e $var
|
|
end
|
|
if not source "${envCache}"
|
|
echo "op-env: cache written but could not be sourced" >&2
|
|
return 1
|
|
end
|
|
echo "op-env: refreshed"
|
|
end
|
|
|
|
function op-env-clear --description "Clear cached secrets"
|
|
if test -f "${envCache}"
|
|
for var in (string match -rg 'set -gx (\S+)' < "${envCache}")
|
|
set -e $var
|
|
end
|
|
command rm -f "${envCache}"
|
|
end
|
|
echo "op-env: cleared"
|
|
end
|
|
|
|
# Source cached secrets (instant, no network)
|
|
if test -f "${envCache}"
|
|
source "${envCache}"
|
|
end
|
|
|
|
# User-local config (OP_SERVICE_ACCOUNT_TOKEN, per-machine overrides)
|
|
if test -f ~/.config/fish/local.fish
|
|
source ~/.config/fish/local.fish
|
|
end
|
|
'';
|
|
};
|
|
}
|