Files
dotfiles/dot_config/fish/functions/pj.fish
T

89 lines
3.3 KiB
Fish
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.
function pj --description "fzf package.json script runner with auto-detected package manager"
# ── Locate nearest package.json (walk up) ──────────────────────────
set -l dir (pwd)
set -l pkg ""
while true
if test -f "$dir/package.json"
set pkg "$dir/package.json"
break
end
test "$dir" = / && break
set dir (path dirname $dir)
end
if test -z "$pkg"
# PJ_QUIET: called from the down-arrow binding, where a missing
# package.json is the normal case and must not print anything.
test -n "$PJ_QUIET"; or echo "pj: no package.json found in this tree" >&2
return 1
end
set -l root (path dirname $pkg)
# ── Detect package manager ─────────────────────────────────────────
# Priority: packageManager field (corepack) → lockfiles (walking up
# past $root to catch monorepo-root locks) → npm fallback
set -l pm (jq -r '.packageManager // empty' $pkg | string split '@')[1]
if test -z "$pm"
set -l d $root
while test -z "$pm"
if test -f "$d/bun.lockb" -o -f "$d/bun.lock"
set pm bun
else if test -f "$d/pnpm-lock.yaml"
set pm pnpm
else if test -f "$d/yarn.lock"
set pm yarn
else if test -f "$d/package-lock.json"
set pm npm
end
test "$d" = / && break
set d (path dirname $d)
end
test -z "$pm" && set pm npm
end
# ── Pick a script ──────────────────────────────────────────────────
set -l script (jq -r '.scripts // {} | keys[]' $pkg | fzf \
--prompt="$pm run ❯ " \
--header="$root" \
--height=40% --layout=reverse --border \
--preview="jq -r --arg s {} '.scripts[\$s]' $pkg" \
--preview-window=up:2:wrap)
test -z "$script" && return 0
# ── Run (npm needs `--` to forward extra args) ────────────────────
set -l extra $argv
if test "$pm" = npm -a (count $extra) -gt 0
set extra -- $extra
end
# Wrap long-running server scripts in openlogs (live log tail for agents).
# Matches dev/start/serve and namespaced variants like dev:web, start:api.
set -l wrapper
if string match -qr '^(dev|start|serve|watch)(:.*)?$' -- $script
# Resolve the binary: PATH → mise resolution → mise installs glob
set -l ol (command -s openlogs)
if test -z "$ol"; and command -sq mise
set ol (mise which openlogs 2>/dev/null)
end
if test -z "$ol"
set ol ~/.local/share/mise/installs/node/*/bin/openlogs
set ol $ol[1]
end
if test -n "$ol" -a -x "$ol"
set wrapper $ol
else
echo "pj: openlogs not found, running unwrapped" >&2
end
end
if test -n "$wrapper"
echo "→ $wrapper $pm run $script $argv" >&2
$wrapper $pm run $script $extra
else
echo "→ $pm run $script $argv" >&2
$pm run $script $extra
end
end