mirror of
https://github.com/prdlk/dotfiles.git
synced 2026-11-02 19:32:43 +00:00
86 lines
3.1 KiB
Fish
86 lines
3.1 KiB
Fish
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"
|
|||
|
|
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
|