diff --git a/install.sh b/install.sh
index f6fdd33..891c49e 100755
--- a/install.sh
+++ b/install.sh
@@ -140,7 +140,7 @@ if should_run 2 scripts; then
done
lib_count=0
lib_names=""
- for lf in common.sh flags.sh notify.sh entertainment-lib.sh scheduler-lib.sh config-ui.sh user-timers-lib.sh entertainment-plugin-lib.sh usb-lib.sh; do
+ for lf in common.sh flags.sh notify.sh entertainment-lib.sh scheduler-lib.sh config-ui.sh user-timers-lib.sh entertainment-plugin-lib.sh usb-lib.sh share-lib.sh menu-lib.sh; do
run sudo install -m 644 "lib/$lf" "/usr/local/bin/$lf"
lib_count=$((lib_count + 1))
lib_names+="$lf "
diff --git a/lib/menu-lib.sh b/lib/menu-lib.sh
new file mode 100644
index 0000000..ef63435
--- /dev/null
+++ b/lib/menu-lib.sh
@@ -0,0 +1,169 @@
+# lib/menu-lib.sh — category-neutral interactive menu primitives.
+#
+# The generic half of the former share-lib interactive layer (Pattern B),
+# extracted so any `pos` tool can share one interaction vocabulary: a tty
+# guard, a looping boxed menu, a type-to-filter picker and a prompt with
+# optional default. Display goes to stderr, results to stdout; reads are
+# stdin-based and fail closed (EOF / no terminal → rc 1, never a hang),
+# so the functions are safe under the dispatcher's logging tee and inside
+# command substitution.
+#
+# Contracts (all of them, no exceptions):
+# * Defines ONLY `menu_*` functions — sourcing never clobbers a tool's own
+# helpers (same discipline as lib/notify.sh).
+# * Requires common.sh to be sourced by the CALLER for colored output;
+# CYAN/RESET get empty guarded fallbacks here so the lib also works
+# standalone-sourced (plain text instead of color — never an error).
+# * NEVER exits and never terminates the caller: every function returns,
+# failures are signalled through the return code.
+# * Display goes to stderr, results go to stdout — any function whose result
+# is meant to be command-substituted prints ONLY the result on stdout.
+# * Performs NO file writes of its own.
+#
+# Function index:
+# menu_guard rc 0 iff stdin is a terminal
+# menu_run
numbered menu loop → chosen index
+# menu_pick type-to-filter picker → chosen index
+# menu_ask_value