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