Extract the runner logic into its own file so the stubs can be minimal

This commit is contained in:
David Heinemeier Hansson
2026-05-22 17:37:43 +02:00
parent 32bfddefc5
commit bbdf873aec
4 changed files with 207 additions and 126 deletions
+6 -60
View File
@@ -1,76 +1,22 @@
#!/bin/bash #!/bin/bash
# omarchy:summary=Install a pnpm dlx wrapper for a given npm package. # omarchy:summary=Install a small pnpm dlx wrapper for a given npm package.
# omarchy:args=<package> [command-name] # omarchy:args=<package> [command-name [bin-name]]
if [[ -z $1 ]]; then if [[ -z $1 ]]; then
echo "Usage: omarchy-npm-install <package> [command-name]" echo "Usage: omarchy-npm-install <package> [command-name [bin-name]]"
exit 1 exit 1
fi fi
package=$1 package=$1
command=${2:-$1} command=${2:-$1}
bin=${3:-$command}
mkdir -p "$HOME/.local/bin" mkdir -p "$HOME/.local/bin"
cat > "$HOME/.local/bin/$command" <<EOF cat >"$HOME/.local/bin/$command" <<EOF
#!/bin/bash #!/bin/bash
package="$package" exec omarchy-npm-run "$package" "$command" "$bin" "\$@"
command="$command"
if ! node_root="\$(mise where node@latest 2>/dev/null)"; then
mise use -g node@latest >/dev/null
node_root="\$(mise where node@latest)"
fi
if omarchy-cmd-missing pnpm; then
echo "Installing pnpm for \$package..."
omarchy-pkg-add pnpm
hash -r
fi
# pnpm reads npm_config_* env vars for CLI configuration.
export npm_config_minimum_release_age=7200
export npm_config_dlx_cache_max_age=7200
ensure_bin_runtime() {
local bin_path=\$1
local shebang
IFS= read -r shebang < "\$bin_path"
if [[ \$shebang == "#!"*"/bun"* || \$shebang == "#!"*"/env bun"* ]]; then
if omarchy-cmd-missing bun; then
echo "Installing bun runtime for \$package..."
omarchy-pkg-add bun
hash -r
fi
fi
}
exec_package_bin() {
local package_bin_path=\$1
shift
if [[ -n \$package_bin_path ]]; then
ensure_bin_runtime "\$package_bin_path"
PATH="\$node_root/bin:\$PATH" exec "\$package_bin_path" "\$@"
fi
}
# Resolve the package bin inside pnpm dlx, then run it with node@latest available for node shebangs.
# Some wrappers are aliases, e.g. playwright-cli wraps the playwright bin.
PATH="\$node_root/bin:\$PATH" pnpm dlx --package "\$package" true
package_bin_path=\$(PATH="\$node_root/bin:\$PATH" pnpm dlx --package "\$package" which "\$package" 2>/dev/null)
exec_package_bin "\$package_bin_path" "\$@"
# Scoped packages like @openai/codex expose an unscoped bin like codex.
package_bin_path=\$(PATH="\$node_root/bin:\$PATH" pnpm dlx --package "\$package" which "\$command" 2>/dev/null)
exec_package_bin "\$package_bin_path" "\$@"
echo "Could not resolve npm bin for \$package / \$command" >&2
exit 127
EOF EOF
chmod +x "$HOME/.local/bin/$command" chmod +x "$HOME/.local/bin/$command"
+76
View File
@@ -0,0 +1,76 @@
#!/bin/bash
# omarchy:summary=Run a pnpm dlx-backed npm package wrapper.
# omarchy:args=<package> <command-name> <bin-name> [args...]
# omarchy:hidden=true
if (($# < 3)); then
echo "Usage: omarchy-npm-run <package> <command-name> <bin-name> [args...]"
exit 1
fi
package=$1
command=$2
bin=$3
shift 3
package_spec=$package
state_dir="${XDG_STATE_HOME:-$HOME/.local/state}/omarchy/npm-wrappers"
version_file="$state_dir/$command.version"
pin_ttl=7200
uses_pinned_version=0
if [[ -s $version_file ]]; then
now=$(date +%s)
pinned_at=$(stat -c %Y "$version_file" 2>/dev/null || printf '0\n')
if ((now - pinned_at < pin_ttl)); then
pinned_version=$(<"$version_file")
package_spec="$package@$pinned_version"
uses_pinned_version=1
else
rm -f "$version_file"
fi
fi
if ! node_root=$(mise where node@latest 2>/dev/null); then
mise use -g node@latest >/dev/null
node_root=$(mise where node@latest)
fi
export PATH="$node_root/bin:$PATH"
if omarchy-cmd-missing pnpm; then
echo "Installing pnpm for $package..."
omarchy-pkg-add pnpm
hash -r
fi
# pnpm reads npm_config_* env vars for CLI configuration.
export npm_config_minimum_release_age=$pin_ttl
export npm_config_dlx_cache_max_age=$pin_ttl
if (( uses_pinned_version )); then
export npm_config_minimum_release_age=0
fi
if (($# == 1)) && [[ $1 == "update" ]]; then
export npm_config_minimum_release_age=0
export npm_config_dlx_cache_max_age=0
if ! latest_version=$(env -u npm_config_minimum_release_age -u npm_config_dlx_cache_max_age pnpm view "$package@latest" version); then
echo "Could not resolve latest npm version for $package" >&2
exit 1
fi
mkdir -p "$state_dir"
printf '%s\n' "$latest_version" >"$version_file"
package_spec="$package@$latest_version"
pnpm dlx --package "$package_spec" true
echo "Updated $command to $latest_version"
exit 0
fi
exec pnpm dlx --package "$package_spec" "$bin" "$@"
+1 -1
View File
@@ -2,7 +2,7 @@ omarchy-npm-install @openai/codex codex
omarchy-npm-install @google/gemini-cli gemini omarchy-npm-install @google/gemini-cli gemini
omarchy-npm-install @github/copilot copilot omarchy-npm-install @github/copilot copilot
omarchy-npm-install opencode-ai opencode omarchy-npm-install opencode-ai opencode
omarchy-npm-install playwright playwright-cli omarchy-npm-install playwright playwright-cli playwright
omarchy-npm-install @earendil-works/pi-coding-agent pi omarchy-npm-install @earendil-works/pi-coding-agent pi
omarchy-npm-install @kitlangton/ghui ghui omarchy-npm-install @kitlangton/ghui ghui
omarchy-npm-install hunkdiff hunk omarchy-npm-install hunkdiff hunk
+124 -65
View File
@@ -16,6 +16,21 @@ fail() {
exit 1 exit 1
} }
assert_file_contains() {
local description="$1"
local file="$2"
local expected="$3"
if ! grep -Fq "$expected" "$file"; then
printf 'Expected %s to contain: %s\n' "$file" "$expected" >&2
printf 'Actual file:\n' >&2
sed -n '1,120p' "$file" >&2
fail "$description"
fi
pass "$description"
}
cleanup() { cleanup() {
[[ -n $TMPDIR && -d $TMPDIR ]] && rm -rf "$TMPDIR" [[ -n $TMPDIR && -d $TMPDIR ]] && rm -rf "$TMPDIR"
} }
@@ -24,60 +39,51 @@ trap cleanup EXIT
TMPDIR=$(mktemp -d) TMPDIR=$(mktemp -d)
HOME="$TMPDIR/home" "$ROOT/bin/omarchy-npm-install" @openai/codex codex HOME="$TMPDIR/home" "$ROOT/bin/omarchy-npm-install" @openai/codex codex
wrapper="$TMPDIR/home/.local/bin/codex" wrapper="$TMPDIR/home/.local/bin/codex"
runtime="$ROOT/bin/omarchy-npm-run"
[[ -x $wrapper ]] || fail "npm wrapper is generated" [[ -x $wrapper ]] || fail "npm wrapper is generated"
pass "npm wrapper is generated" pass "npm wrapper is generated"
if ! grep -q "npm_config_minimum_release_age=7200" "$wrapper"; then assert_file_contains "npm wrapper defaults bin to command name" "$wrapper" 'exec omarchy-npm-run "@openai/codex" "codex" "codex" "$@"'
fail "npm wrapper configures pnpm minimum release age"
fi
pass "npm wrapper configures pnpm minimum release age"
if ! grep -q "npm_config_dlx_cache_max_age=7200" "$wrapper"; then if grep -q "pnpm dlx" "$wrapper"; then
fail "npm wrapper configures pnpm dlx cache max age" fail "npm wrapper does not inline pnpm runtime"
fi fi
pass "npm wrapper configures pnpm dlx cache max age" pass "npm wrapper does not inline pnpm runtime"
if grep -q "PNPM_CONFIG_MINIMUM_RELEASE_AGE" "$wrapper"; then HOME="$TMPDIR/home" "$ROOT/bin/omarchy-npm-install" playwright playwright-cli playwright
fail "npm wrapper does not use ignored PNPM_CONFIG env vars" assert_file_contains "npm wrapper records explicit package bin" "$TMPDIR/home/.local/bin/playwright-cli" 'exec omarchy-npm-run "playwright" "playwright-cli" "playwright" "$@"'
assert_file_contains "npm runtime defines pin ttl" "$runtime" "pin_ttl=7200"
assert_file_contains "npm runtime configures pnpm minimum release age" "$runtime" 'npm_config_minimum_release_age=$pin_ttl'
assert_file_contains "npm runtime configures pnpm dlx cache max age" "$runtime" 'npm_config_dlx_cache_max_age=$pin_ttl'
if grep -q "PNPM_CONFIG_MINIMUM_RELEASE_AGE" "$runtime"; then
fail "npm runtime does not use ignored PNPM_CONFIG env vars"
fi fi
pass "npm wrapper does not use ignored PNPM_CONFIG env vars" pass "npm runtime does not use ignored PNPM_CONFIG env vars"
removed_flag="--force""-update" removed_flag="--force""-update"
if grep -q -- "$removed_flag" "$wrapper"; then if grep -q -- "$removed_flag" "$runtime"; then
fail "npm wrapper does not expose removed force update flag" fail "npm runtime does not expose removed force update flag"
fi fi
pass "npm wrapper does not expose removed force update flag" pass "npm runtime does not expose removed force update flag"
if ! grep -q "npm_config_dlx_cache_max_age=0" "$wrapper"; then if grep -q " which " "$runtime"; then
fail "npm wrapper update bypasses dlx cache" fail "npm runtime does not discover package bins dynamically"
fi fi
pass "npm wrapper update bypasses dlx cache" pass "npm runtime does not discover package bins dynamically"
if ! grep -q "npm_config_minimum_release_age=0" "$wrapper"; then
fail "npm wrapper update bypasses minimum release age"
fi
pass "npm wrapper update bypasses minimum release age"
if ! grep -q "wrapper_update=1" "$wrapper"; then
fail "npm wrapper maps update to wrapper update"
fi
pass "npm wrapper maps update to wrapper update"
if ! grep -q "version_file=" "$wrapper"; then
fail "npm wrapper persists update version"
fi
pass "npm wrapper persists update version"
stub_bin="$TMPDIR/bin" stub_bin="$TMPDIR/bin"
node_root="$TMPDIR/node" node_root="$TMPDIR/node"
package_bin="$TMPDIR/package-bin" state_home="$TMPDIR/state"
pnpm_log="$TMPDIR/pnpm.log" pnpm_log="$TMPDIR/pnpm.log"
package_args="$TMPDIR/package-args" package_args="$TMPDIR/package-args"
version_file="$state_home/omarchy/npm-wrappers/codex.version"
mkdir -p "$stub_bin" "$node_root/bin" mkdir -p "$stub_bin" "$node_root/bin"
cat > "$stub_bin/mise" <<'SH' cat >"$stub_bin/mise" <<'SH'
#!/bin/bash #!/bin/bash
if [[ $1 == "where" && $2 == "node@latest" ]]; then if [[ $1 == "where" && $2 == "node@latest" ]]; then
printf '%s\n' "$OMARCHY_NPM_TEST_NODE_ROOT" printf '%s\n' "$OMARCHY_NPM_TEST_NODE_ROOT"
@@ -87,12 +93,12 @@ fi
exit 1 exit 1
SH SH
cat > "$stub_bin/omarchy-cmd-missing" <<'SH' cat >"$stub_bin/omarchy-cmd-missing" <<'SH'
#!/bin/bash #!/bin/bash
exit 1 exit 1
SH SH
cat > "$stub_bin/pnpm" <<'SH' cat >"$stub_bin/pnpm" <<'SH'
#!/bin/bash #!/bin/bash
printf 'min_age=%s dlx_cache=%s args=%s\n' "${npm_config_minimum_release_age:-}" "${npm_config_dlx_cache_max_age:-}" "$*" >>"$OMARCHY_NPM_TEST_PNPM_LOG" printf 'min_age=%s dlx_cache=%s args=%s\n' "${npm_config_minimum_release_age:-}" "${npm_config_dlx_cache_max_age:-}" "$*" >>"$OMARCHY_NPM_TEST_PNPM_LOG"
@@ -101,57 +107,79 @@ if [[ $1 == "view" ]]; then
exit 0 exit 0
fi fi
if [[ $1 == "dlx" && $4 == "true" ]]; then if [[ $1 == "dlx" ]]; then
exit 0 if [[ $4 == "true" ]]; then
fi exit 0
fi
if [[ $1 == "dlx" && $4 == "which" ]]; then shift 4
printf '%s\n' "$OMARCHY_NPM_TEST_PACKAGE_BIN" printf '%s\n' "$*" >"$OMARCHY_NPM_TEST_PACKAGE_ARGS"
exit 0 exit 0
fi fi
exit 1 exit 1
SH SH
cat > "$package_bin" <<'SH' chmod +x "$stub_bin/mise" "$stub_bin/omarchy-cmd-missing" "$stub_bin/pnpm"
#!/bin/bash
printf '%s\n' "$*" >"$OMARCHY_NPM_TEST_PACKAGE_ARGS"
SH
chmod +x "$stub_bin/mise" "$stub_bin/omarchy-cmd-missing" "$stub_bin/pnpm" "$package_bin"
OMARCHY_NPM_TEST_NODE_ROOT="$node_root" \ OMARCHY_NPM_TEST_NODE_ROOT="$node_root" \
OMARCHY_NPM_TEST_PACKAGE_BIN="$package_bin" \
OMARCHY_NPM_TEST_PACKAGE_ARGS="$package_args" \ OMARCHY_NPM_TEST_PACKAGE_ARGS="$package_args" \
OMARCHY_NPM_TEST_PNPM_LOG="$pnpm_log" \ OMARCHY_NPM_TEST_PNPM_LOG="$pnpm_log" \
HOME="$TMPDIR/home" \
XDG_STATE_HOME="$state_home" \
PATH="$stub_bin:$PATH" \ PATH="$stub_bin:$PATH" \
"$wrapper" -s danger-full-access update alpha beta "$wrapper" -s danger-full-access update alpha beta
if ! grep -q "dlx_cache=0" "$pnpm_log"; then if ! grep -Fq "args=dlx --package @openai/codex codex -s danger-full-access update alpha beta" "$pnpm_log"; then
fail "update sets pnpm dlx cache age to zero" fail "non-leading update is forwarded to package bin"
fi fi
pass "update sets pnpm dlx cache age to zero" pass "non-leading update is forwarded to package bin"
if ! grep -q "min_age=0" "$pnpm_log"; then if ! grep -q "dlx_cache=7200" "$pnpm_log"; then
fail "update sets pnpm minimum release age to zero" fail "normal run uses pnpm dlx cache age"
fi fi
pass "update sets pnpm minimum release age to zero" pass "normal run uses pnpm dlx cache age"
if ! grep -q "args=dlx --package @openai/codex@1.2.3 true" "$pnpm_log"; then if ! grep -q "min_age=7200" "$pnpm_log"; then
fail "update uses resolved latest package version" fail "normal run uses pnpm minimum release age"
fi fi
pass "update uses resolved latest package version" pass "normal run uses pnpm minimum release age"
if [[ -f $package_args ]]; then if [[ $(<"$package_args") != "-s danger-full-access update alpha beta" ]]; then
fail "update does not run the package bin" fail "normal run forwards package args"
fi fi
pass "update does not run the package bin" pass "normal run forwards package args"
if [[ -f $version_file ]]; then
fail "non-leading update does not pin wrapper version"
fi
pass "non-leading update does not pin wrapper version"
rm -f "$pnpm_log" "$package_args" rm -f "$pnpm_log" "$package_args"
OMARCHY_NPM_TEST_NODE_ROOT="$node_root" \ OMARCHY_NPM_TEST_NODE_ROOT="$node_root" \
OMARCHY_NPM_TEST_PACKAGE_BIN="$package_bin" \
OMARCHY_NPM_TEST_PACKAGE_ARGS="$package_args" \ OMARCHY_NPM_TEST_PACKAGE_ARGS="$package_args" \
OMARCHY_NPM_TEST_PNPM_LOG="$pnpm_log" \ OMARCHY_NPM_TEST_PNPM_LOG="$pnpm_log" \
HOME="$TMPDIR/home" \
XDG_STATE_HOME="$state_home" \
PATH="$stub_bin:$PATH" \
"$wrapper" update alpha
if ! grep -Fq "args=dlx --package @openai/codex codex update alpha" "$pnpm_log"; then
fail "update with extra args is forwarded to package bin"
fi
pass "update with extra args is forwarded to package bin"
if [[ -f $version_file ]]; then
fail "update with extra args does not pin wrapper version"
fi
pass "update with extra args does not pin wrapper version"
rm -f "$pnpm_log" "$package_args"
OMARCHY_NPM_TEST_NODE_ROOT="$node_root" \
OMARCHY_NPM_TEST_PACKAGE_ARGS="$package_args" \
OMARCHY_NPM_TEST_PNPM_LOG="$pnpm_log" \
HOME="$TMPDIR/home" \
XDG_STATE_HOME="$state_home" \
PATH="$stub_bin:$PATH" \ PATH="$stub_bin:$PATH" \
"$wrapper" update "$wrapper" update
@@ -165,25 +193,31 @@ if ! grep -q "min_age=0" "$pnpm_log"; then
fi fi
pass "wrapper update bypasses pnpm minimum release age" pass "wrapper update bypasses pnpm minimum release age"
if ! grep -q "args=dlx --package @openai/codex@1.2.3 true" "$pnpm_log"; then if ! grep -Fq "args=dlx --package @openai/codex@1.2.3 true" "$pnpm_log"; then
fail "wrapper update uses resolved latest package version" fail "wrapper update uses resolved latest package version"
fi fi
pass "wrapper update uses resolved latest package version" pass "wrapper update uses resolved latest package version"
if [[ -f $package_args ]]; then if [[ -f $package_args ]]; then
fail "wrapper update does not run package self-updater" fail "wrapper update does not run package bin"
fi fi
pass "wrapper update does not run package self-updater" pass "wrapper update does not run package bin"
if [[ $(<"$version_file") != "1.2.3" ]]; then
fail "wrapper update persists resolved version"
fi
pass "wrapper update persists resolved version"
rm -f "$pnpm_log" "$package_args" rm -f "$pnpm_log" "$package_args"
OMARCHY_NPM_TEST_NODE_ROOT="$node_root" \ OMARCHY_NPM_TEST_NODE_ROOT="$node_root" \
OMARCHY_NPM_TEST_PACKAGE_BIN="$package_bin" \
OMARCHY_NPM_TEST_PACKAGE_ARGS="$package_args" \ OMARCHY_NPM_TEST_PACKAGE_ARGS="$package_args" \
OMARCHY_NPM_TEST_PNPM_LOG="$pnpm_log" \ OMARCHY_NPM_TEST_PNPM_LOG="$pnpm_log" \
HOME="$TMPDIR/home" \
XDG_STATE_HOME="$state_home" \
PATH="$stub_bin:$PATH" \ PATH="$stub_bin:$PATH" \
"$wrapper" gamma "$wrapper" gamma
if ! grep -q "args=dlx --package @openai/codex@1.2.3 true" "$pnpm_log"; then if ! grep -Fq "args=dlx --package @openai/codex@1.2.3 codex gamma" "$pnpm_log"; then
fail "wrapper reuses pinned update version" fail "wrapper reuses pinned update version"
fi fi
pass "wrapper reuses pinned update version" pass "wrapper reuses pinned update version"
@@ -197,3 +231,28 @@ if [[ $(<"$package_args") != "gamma" ]]; then
fail "wrapper forwards args after pinned update" fail "wrapper forwards args after pinned update"
fi fi
pass "wrapper forwards args after pinned update" pass "wrapper forwards args after pinned update"
rm -f "$pnpm_log" "$package_args"
touch -d "@$(($(date +%s) - 7201))" "$version_file"
OMARCHY_NPM_TEST_NODE_ROOT="$node_root" \
OMARCHY_NPM_TEST_PACKAGE_ARGS="$package_args" \
OMARCHY_NPM_TEST_PNPM_LOG="$pnpm_log" \
HOME="$TMPDIR/home" \
XDG_STATE_HOME="$state_home" \
PATH="$stub_bin:$PATH" \
"$wrapper" delta
if ! grep -Fq "args=dlx --package @openai/codex codex delta" "$pnpm_log"; then
fail "wrapper drops expired pinned update version"
fi
pass "wrapper drops expired pinned update version"
if ! grep -q "min_age=7200" "$pnpm_log"; then
fail "wrapper restores minimum release age after pin expiry"
fi
pass "wrapper restores minimum release age after pin expiry"
if [[ -f $version_file ]]; then
fail "wrapper removes expired pinned version file"
fi
pass "wrapper removes expired pinned version file"