opx.fish

 1function opx --description "Run command with 1Password secret refs resolved"
 2    set -l vars_to_resolve
 3    set -l refs
 4
 5    for var in (set --names -x)
 6        set -l value $$var
 7        if string match -q 'op://*' -- $value
 8            set -a vars_to_resolve $var
 9            set -a refs $value
10        end
11    end
12
13    if test (count $vars_to_resolve) -eq 0
14        $argv
15        return
16    end
17
18    # Build template: VAR=op://ref (one per line)
19    set -l template_lines
20    for i in (seq (count $vars_to_resolve))
21        set -a template_lines "$vars_to_resolve[$i]=$refs[$i]"
22    end
23
24    # Single op call resolves everything
25    set -l resolved_lines (printf '%s\n' $template_lines | op inject 2>/dev/null)
26    if test $status -ne 0
27        echo "opx: failed to resolve secrets" >&2
28        return 1
29    end
30
31    # Check if the command is a fish function
32    if functions -q $argv[1]
33        # Parse resolved values (originals are in $refs)
34        set -l resolved_values
35        for line in $resolved_lines
36            set -a resolved_values (string split -m1 '=' $line)[2]
37        end
38        # Set globals with resolved values
39        for i in (seq (count $vars_to_resolve))
40            set -gx $vars_to_resolve[$i] $resolved_values[$i]
41        end
42        # Run command
43        $argv
44        set -l cmd_status $status
45        # Restore original op:// refs
46        for i in (seq (count $vars_to_resolve))
47            set -gx $vars_to_resolve[$i] $refs[$i]
48        end
49        return $cmd_status
50    else
51        env $resolved_lines $argv
52    end
53end