fpf-cli 1.6.29 → 1.6.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -74,6 +74,7 @@ Live reload is enabled by default, with a minimum query length and debounce to r
74
74
  - `-R, --remove` remove selected packages
75
75
  - `-U, --update` run update/upgrade flow
76
76
  - `--refresh` refresh package catalogs only
77
+ - `-y, --yes` skip confirmation prompts
77
78
  - `-v, --version` print version and exit
78
79
  - `-h, --help` show help
79
80
 
@@ -90,12 +91,14 @@ Installed packages are marked with `*` in the result list.
90
91
  ## Notes
91
92
 
92
93
  - Requires: `bash` + `fzf`
93
- - If `fzf` is missing, `fpf` auto-installs it using a compatible detected manager.
94
+ - If `fzf` is missing, `fpf` auto-installs it using a compatible detected manager, then falls back to a release binary download if manager bootstrap fails.
94
95
  - Root managers (`apt`, `dnf`, `pacman`, `zypper`, `emerge`, `snap`) use `sudo` when needed.
95
96
  - If Flatpak is detected and Flathub is missing, `fpf` attempts `flatpak remote-add --if-not-exists --user flathub ...` automatically.
97
+ - Set `FPF_ASSUME_YES=1` to bypass confirmation prompts in non-interactive flows.
96
98
  - `FPF_DYNAMIC_RELOAD`: `always` (default), `single`, or `never`
97
99
  - Live reload uses `change:reload` by default for reliability (`ctrl-r` uses the same reload command).
98
100
  - Set `FPF_DYNAMIC_RELOAD_TRANSPORT=ipc` to opt into `--listen` + IPC query notifications on supported `fzf` builds.
99
101
  - `FPF_RELOAD_MIN_CHARS`: minimum query length before live reload (default `2`)
100
102
  - `FPF_RELOAD_DEBOUNCE`: reload debounce seconds (default `0.12`)
101
103
  - `FPF_DISABLE_INSTALLED_CACHE=1` disables installed-package marker cache
104
+ - `FPF_INSTALLED_CACHE_TTL`: installed-package marker cache freshness window in seconds (default `300`, set `0` to always refresh)
package/fpf CHANGED
@@ -3,7 +3,7 @@
3
3
  set -euo pipefail
4
4
 
5
5
  SCRIPT_NAME="fpf"
6
- SCRIPT_VERSION="1.6.29"
6
+ SCRIPT_VERSION="1.6.31"
7
7
  TMP_ROOT="${TMPDIR:-/tmp}/fpf"
8
8
  SESSION_TMP_ROOT=""
9
9
  HELP_FILE=""
@@ -15,7 +15,9 @@ ACTION="search"
15
15
  MANAGER_OVERRIDE=""
16
16
  IPC_MANAGER_OVERRIDE=""
17
17
  IPC_FALLBACK_FILE=""
18
+ ASSUME_YES="0"
18
19
  declare -a QUERY_PARTS=()
20
+ FPF_LIBRARIES_LOADED="0"
19
21
 
20
22
  query_cache_flags() {
21
23
  printf "%s" "query_limit=${FPF_QUERY_RESULT_LIMIT:-0};per_manager_limit=${FPF_QUERY_PER_MANAGER_LIMIT:-40};no_query_limit=${FPF_NO_QUERY_RESULT_LIMIT:-120};no_query_npm_limit=${FPF_NO_QUERY_NPM_LIMIT:-120}"
@@ -34,6 +36,74 @@ command_exists() {
34
36
  command -v "$1" >/dev/null 2>&1
35
37
  }
36
38
 
39
+ resolve_script_dir() {
40
+ local script_path="${BASH_SOURCE[0]}"
41
+ local script_dir=""
42
+
43
+ if command_exists readlink; then
44
+ while [[ -L "${script_path}" ]]; do
45
+ script_dir="$(cd -P "$(dirname "${script_path}")" && pwd)"
46
+ script_path="$(readlink "${script_path}")"
47
+ if [[ "${script_path}" != /* ]]; then
48
+ script_path="${script_dir}/${script_path}"
49
+ fi
50
+ done
51
+ fi
52
+
53
+ if [[ "${script_path}" != /* ]]; then
54
+ script_path="$(pwd)/${script_path}"
55
+ fi
56
+
57
+ script_dir="$(cd -P "$(dirname "${script_path}")" && pwd)"
58
+ printf "%s" "${script_dir}"
59
+ }
60
+
61
+ load_fpf_libraries() {
62
+ local script_dir=""
63
+ local manager_actions_lib=""
64
+
65
+ if [[ "${FPF_LIBRARIES_LOADED}" == "1" ]]; then
66
+ return
67
+ fi
68
+
69
+ script_dir="$(resolve_script_dir)"
70
+ manager_actions_lib="${script_dir}/lib/fpf/manager-actions.sh"
71
+
72
+ if [[ ! -r "${manager_actions_lib}" ]]; then
73
+ die "Required library file not found: ${manager_actions_lib}"
74
+ fi
75
+
76
+ # shellcheck disable=SC1090
77
+ source "${manager_actions_lib}"
78
+ FPF_LIBRARIES_LOADED="1"
79
+ }
80
+
81
+ fzf_command_available() {
82
+ if [[ "${FPF_TEST_FORCE_FZF_MISSING:-0}" == "1" ]]; then
83
+ if [[ -n "${FPF_TEST_MOCK_BIN:-}" && -x "${FPF_TEST_MOCK_BIN}/fzf" ]]; then
84
+ return 0
85
+ fi
86
+ return 1
87
+ fi
88
+
89
+ command_exists fzf
90
+ }
91
+
92
+ assume_yes_enabled() {
93
+ if [[ "${ASSUME_YES}" == "1" ]]; then
94
+ return 0
95
+ fi
96
+
97
+ case "${FPF_ASSUME_YES:-0}" in
98
+ 1|true|TRUE|yes|YES|on|ON)
99
+ return 0
100
+ ;;
101
+ *)
102
+ return 1
103
+ ;;
104
+ esac
105
+ }
106
+
37
107
  ensure_tmp_root() {
38
108
  mkdir -p "${TMP_ROOT}"
39
109
  }
@@ -146,30 +216,127 @@ cache_catalog_key() {
146
216
  printf "catalog/%s.tsv" "${manager}"
147
217
  }
148
218
 
219
+ catalog_fixture_checksum() {
220
+ local fixture_name="$1"
221
+ local fixture_path=""
222
+
223
+ if [[ "${FPF_TEST_FIXTURES:-0}" != "1" ]]; then
224
+ return 1
225
+ fi
226
+
227
+ if [[ -z "${FPF_TEST_FIXTURE_DIR:-}" ]]; then
228
+ return 1
229
+ fi
230
+
231
+ fixture_path="${FPF_TEST_FIXTURE_DIR}/${fixture_name}"
232
+ [[ -r "${fixture_path}" ]] || return 1
233
+ cksum "${fixture_path}" | awk '{ print $1 }'
234
+ }
235
+
236
+ apt_catalog_state_token() {
237
+ local fixture_checksum=""
238
+ local lists_dir="/var/lib/apt/lists"
239
+ local listing=""
240
+ local listing_checksum=""
241
+ local policy_checksum=""
242
+
243
+ fixture_checksum="$(catalog_fixture_checksum "apt-dumpavail.txt" 2>/dev/null || true)"
244
+ if [[ -n "${fixture_checksum}" ]]; then
245
+ printf "fixture=%s" "${fixture_checksum}"
246
+ return
247
+ fi
248
+
249
+ if [[ -d "${lists_dir}" ]]; then
250
+ listing="$(find "${lists_dir}" -maxdepth 1 -type f \( -name '*_Packages' -o -name '*_Sources' -o -name '*InRelease' -o -name '*Release' \) -printf '%f|%s|%T@\n' 2>/dev/null | LC_ALL=C sort || true)"
251
+ if [[ -n "${listing}" ]]; then
252
+ listing_checksum="$(printf "%s" "${listing}" | cksum | awk '{ print $1 }')"
253
+ printf "lists=%s" "${listing_checksum}"
254
+ return
255
+ fi
256
+ fi
257
+
258
+ if command_exists apt-cache; then
259
+ policy_checksum="$(apt-cache policy 2>/dev/null | cksum | awk '{ print $1 }' || true)"
260
+ if [[ -n "${policy_checksum}" ]]; then
261
+ printf "policy=%s" "${policy_checksum}"
262
+ return
263
+ fi
264
+ fi
265
+
266
+ printf "state=unknown"
267
+ }
268
+
269
+ brew_catalog_state_token() {
270
+ local formula_fixture_checksum=""
271
+ local cask_fixture_checksum=""
272
+ local formula_repo=""
273
+ local cask_repo=""
274
+ local formula_head=""
275
+ local cask_head=""
276
+ local brew_version=""
277
+
278
+ formula_fixture_checksum="$(catalog_fixture_checksum "brew-formulae.txt" 2>/dev/null || true)"
279
+ cask_fixture_checksum="$(catalog_fixture_checksum "brew-casks.txt" 2>/dev/null || true)"
280
+ if [[ -n "${formula_fixture_checksum}" || -n "${cask_fixture_checksum}" ]]; then
281
+ printf "fixture=formula=%s;cask=%s" "${formula_fixture_checksum:-missing}" "${cask_fixture_checksum:-missing}"
282
+ return
283
+ fi
284
+
285
+ if command_exists brew; then
286
+ formula_repo="$(brew --repository 2>/dev/null || true)"
287
+ cask_repo="$(brew --repository homebrew/cask 2>/dev/null || true)"
288
+ fi
289
+
290
+ if command_exists git; then
291
+ if [[ -n "${formula_repo}" && -d "${formula_repo}/.git" ]]; then
292
+ formula_head="$(git -C "${formula_repo}" rev-parse HEAD 2>/dev/null || true)"
293
+ fi
294
+ if [[ -n "${cask_repo}" && -d "${cask_repo}/.git" ]]; then
295
+ cask_head="$(git -C "${cask_repo}" rev-parse HEAD 2>/dev/null || true)"
296
+ fi
297
+ fi
298
+
299
+ if [[ -n "${formula_head}" || -n "${cask_head}" ]]; then
300
+ printf "repos=formula:%s;cask:%s" "${formula_head:-missing}" "${cask_head:-missing}"
301
+ return
302
+ fi
303
+
304
+ if [[ -n "${formula_repo}" || -n "${cask_repo}" ]]; then
305
+ printf "repo-paths=formula:%s;cask:%s" "${formula_repo:-missing}" "${cask_repo:-missing}"
306
+ return
307
+ fi
308
+
309
+ if command_exists brew; then
310
+ brew_version="$(brew --version 2>/dev/null | awk 'NR == 1 { print $0; exit }' || true)"
311
+ if [[ -n "${brew_version}" ]]; then
312
+ printf "version=%s" "${brew_version}"
313
+ return
314
+ fi
315
+ fi
316
+
317
+ printf "state=unknown"
318
+ }
319
+
149
320
  cache_search_catalog_fingerprint() {
150
321
  local manager="$1"
151
322
  local command_path=""
152
- local extra_token=""
323
+ local state_token="state=unknown"
153
324
 
154
325
  case "${manager}" in
155
326
  apt)
156
327
  command_path="$(command -v apt-cache 2>/dev/null || printf "missing")"
157
- if [[ "${FPF_TEST_FIXTURES:-0}" == "1" ]]; then
158
- extra_token="|fixtures=${FPF_TEST_FIXTURE_DIR:-enabled}"
159
- fi
328
+ state_token="$(apt_catalog_state_token)"
160
329
  ;;
161
330
  brew)
162
331
  command_path="$(command -v brew 2>/dev/null || printf "missing")"
163
- if [[ "${FPF_TEST_FIXTURES:-0}" == "1" ]]; then
164
- extra_token="|fixtures=${FPF_TEST_FIXTURE_DIR:-enabled}"
165
- fi
332
+ state_token="$(brew_catalog_state_token)"
166
333
  ;;
167
334
  *)
168
335
  command_path="n/a"
169
336
  ;;
170
337
  esac
171
338
 
172
- printf "%s|cmd=%s%s" "$(cache_fingerprint "${manager}" "" "search-catalog")" "${command_path}" "${extra_token}"
339
+ printf "%s|cmd=%s|%s" "$(cache_fingerprint "${manager}" "" "search-catalog")" "${command_path}" "${state_token}"
173
340
  }
174
341
 
175
342
  cache_search_catalog_key() {
@@ -660,53 +827,7 @@ run_preview_manager_output() {
660
827
  local manager="$1"
661
828
  local package="$2"
662
829
 
663
- case "${manager}" in
664
- apt)
665
- apt-cache show "${package}" 2>/dev/null || true
666
- printf "\n"
667
- dpkg -L "${package}" 2>/dev/null || true
668
- ;;
669
- dnf)
670
- dnf info "${package}" 2>/dev/null || true
671
- printf "\n"
672
- rpm -ql "${package}" 2>/dev/null || true
673
- ;;
674
- pacman)
675
- pacman -Si "${package}" 2>/dev/null || true
676
- printf "\n"
677
- pacman -Fl "${package}" 2>/dev/null | awk '{print $2}' || true
678
- ;;
679
- zypper)
680
- zypper --non-interactive info "${package}" 2>/dev/null || true
681
- ;;
682
- emerge)
683
- emerge --search --color=n "${package}" 2>/dev/null || true
684
- ;;
685
- brew)
686
- brew info "${package}" 2>/dev/null || true
687
- ;;
688
- winget)
689
- winget show --id "${package}" --exact --source winget --accept-source-agreements --disable-interactivity 2>/dev/null || true
690
- ;;
691
- choco)
692
- choco info "${package}" 2>/dev/null || true
693
- ;;
694
- scoop)
695
- scoop info "${package}" 2>/dev/null || true
696
- ;;
697
- snap)
698
- snap info "${package}" 2>/dev/null || true
699
- ;;
700
- flatpak)
701
- flatpak info "${package}" 2>/dev/null || flatpak remote-info flathub "${package}" 2>/dev/null || true
702
- ;;
703
- npm)
704
- npm view "${package}" 2>/dev/null || true
705
- ;;
706
- bun)
707
- bun info "${package}" 2>/dev/null || npm view "${package}" 2>/dev/null || true
708
- ;;
709
- esac
830
+ manager_show_info "${manager}" "${package}" || true
710
831
  }
711
832
 
712
833
  run_preview_item_action() {
@@ -999,6 +1120,10 @@ manager_can_install_fzf() {
999
1120
  install_fzf_with_manager() {
1000
1121
  local manager="$1"
1001
1122
 
1123
+ if [[ "${FPF_TEST_FZF_MANAGER_INSTALL_FAIL:-0}" == "1" ]]; then
1124
+ return 1
1125
+ fi
1126
+
1002
1127
  case "${manager}" in
1003
1128
  apt)
1004
1129
  run_as_root apt-get install -y fzf
@@ -1037,6 +1162,105 @@ install_fzf_with_manager() {
1037
1162
  esac
1038
1163
  }
1039
1164
 
1165
+ detect_fzf_release_asset() {
1166
+ local os=""
1167
+ local arch=""
1168
+
1169
+ os="$(uname -s)"
1170
+ arch="$(uname -m)"
1171
+
1172
+ case "${os}" in
1173
+ Linux)
1174
+ case "${arch}" in
1175
+ x86_64|amd64) printf "linux_amd64.tar.gz" ;;
1176
+ aarch64|arm64) printf "linux_arm64.tar.gz" ;;
1177
+ armv7l|armv7*) printf "linux_armv7.tar.gz" ;;
1178
+ armv6l|armv6*) printf "linux_armv6.tar.gz" ;;
1179
+ *) return 1 ;;
1180
+ esac
1181
+ ;;
1182
+ Darwin)
1183
+ case "${arch}" in
1184
+ x86_64|amd64) printf "darwin_amd64.tar.gz" ;;
1185
+ arm64|aarch64) printf "darwin_arm64.tar.gz" ;;
1186
+ *) return 1 ;;
1187
+ esac
1188
+ ;;
1189
+ *)
1190
+ return 1
1191
+ ;;
1192
+ esac
1193
+ }
1194
+
1195
+ resolve_fzf_release_url() {
1196
+ local asset_suffix="$1"
1197
+ local api_url="https://api.github.com/repos/junegunn/fzf/releases/latest"
1198
+ local api_payload=""
1199
+ local asset_url=""
1200
+
1201
+ if [[ -n "${FPF_FZF_BOOTSTRAP_URL:-}" ]]; then
1202
+ printf "%s" "${FPF_FZF_BOOTSTRAP_URL}"
1203
+ return 0
1204
+ fi
1205
+
1206
+ command_exists curl || return 1
1207
+ api_payload="$(curl --silent --show-error --fail --location "${api_url}" 2>/dev/null || true)"
1208
+ [[ -n "${api_payload}" ]] || return 1
1209
+
1210
+ asset_url="$(printf "%s" "${api_payload}" | awk -F'"' -v suffix="${asset_suffix}" '
1211
+ $2 == "browser_download_url" {
1212
+ needle = "-" suffix
1213
+ if (index($4, needle) > 0) {
1214
+ print $4
1215
+ exit
1216
+ }
1217
+ }
1218
+ ')"
1219
+
1220
+ [[ -n "${asset_url}" ]] || return 1
1221
+ printf "%s" "${asset_url}"
1222
+ }
1223
+
1224
+ install_fzf_from_release_fallback() {
1225
+ local asset_suffix=""
1226
+ local asset_url=""
1227
+ local archive_file=""
1228
+ local install_dir=""
1229
+
1230
+ if [[ "${FPF_TEST_BOOTSTRAP_FZF_FALLBACK:-0}" == "1" ]]; then
1231
+ if [[ -n "${FPF_TEST_MOCKCMD_PATH:-}" && -n "${FPF_TEST_MOCK_BIN:-}" ]]; then
1232
+ ln -sf "${FPF_TEST_MOCKCMD_PATH}" "${FPF_TEST_MOCK_BIN}/fzf"
1233
+ return 0
1234
+ fi
1235
+ return 1
1236
+ fi
1237
+
1238
+ asset_suffix="$(detect_fzf_release_asset)" || return 1
1239
+ asset_url="$(resolve_fzf_release_url "${asset_suffix}")" || return 1
1240
+ archive_file="$(mktemp "${SESSION_TMP_ROOT}/fzf-bootstrap.XXXXXX.tar.gz")"
1241
+ install_dir="${SESSION_TMP_ROOT}/fzf-bootstrap/bin"
1242
+
1243
+ mkdir -p "${install_dir}"
1244
+
1245
+ if ! curl --silent --show-error --fail --location --output "${archive_file}" "${asset_url}"; then
1246
+ rm -f "${archive_file}"
1247
+ return 1
1248
+ fi
1249
+
1250
+ if ! tar -xzf "${archive_file}" -C "${install_dir}"; then
1251
+ rm -f "${archive_file}"
1252
+ return 1
1253
+ fi
1254
+
1255
+ rm -f "${archive_file}"
1256
+ chmod +x "${install_dir}/fzf" 2>/dev/null || true
1257
+ [[ -x "${install_dir}/fzf" ]] || return 1
1258
+
1259
+ PATH="${install_dir}:${PATH}"
1260
+ export PATH
1261
+ return 0
1262
+ }
1263
+
1040
1264
  build_fzf_bootstrap_candidates() {
1041
1265
  local seen=""
1042
1266
  local manager
@@ -1074,7 +1298,7 @@ ensure_fzf() {
1074
1298
  local candidates=()
1075
1299
  local manager
1076
1300
 
1077
- if [[ "${FPF_TEST_FORCE_FZF_MISSING:-0}" != "1" ]] && command_exists fzf; then
1301
+ if fzf_command_available; then
1078
1302
  return
1079
1303
  fi
1080
1304
 
@@ -1095,12 +1319,17 @@ ensure_fzf() {
1095
1319
  for manager in "${candidates[@]-}"; do
1096
1320
  log "Attempting fzf install with $(manager_label "${manager}")"
1097
1321
  if install_fzf_with_manager "${manager}"; then
1098
- if command_exists fzf; then
1322
+ if fzf_command_available; then
1099
1323
  return
1100
1324
  fi
1101
1325
  fi
1102
1326
  done
1103
1327
 
1328
+ log "Package-manager bootstrap did not provide fzf. Trying release binary fallback."
1329
+ if install_fzf_from_release_fallback && fzf_command_available; then
1330
+ return
1331
+ fi
1332
+
1104
1333
  die "Failed to auto-install fzf. Install fzf manually and rerun."
1105
1334
  }
1106
1335
 
@@ -1317,6 +1546,7 @@ Action options:
1317
1546
  -R, --remove Fuzzy-search installed packages and remove selected
1318
1547
  -U, --update Run manager update/upgrade flow
1319
1548
  --refresh Refresh manager package catalogs only
1549
+ -y, --yes Assume yes for confirmation prompts
1320
1550
  -v, --version Print version and exit
1321
1551
  -h, --help Show this help
1322
1552
 
@@ -1394,6 +1624,9 @@ parse_args() {
1394
1624
  --refresh)
1395
1625
  ACTION="refresh"
1396
1626
  ;;
1627
+ -y|--yes)
1628
+ ASSUME_YES="1"
1629
+ ;;
1397
1630
  --feed-search)
1398
1631
  ACTION="feed-search"
1399
1632
  ;;
@@ -1570,6 +1803,7 @@ rank_display_rows_by_query() {
1570
1803
  }
1571
1804
  }
1572
1805
  {
1806
+ mgr = lower($1)
1573
1807
  pkg = $2
1574
1808
  desc = $3
1575
1809
 
@@ -2241,23 +2475,101 @@ manager_installed_names() {
2241
2475
  manager_installed_entries "${manager}" | awk -F'\t' 'NF > 0 { print $1 }'
2242
2476
  }
2243
2477
 
2478
+ installed_cache_ttl_seconds() {
2479
+ local ttl_seconds="${FPF_INSTALLED_CACHE_TTL:-300}"
2480
+
2481
+ if ! [[ "${ttl_seconds}" =~ ^[0-9]+$ ]]; then
2482
+ ttl_seconds="300"
2483
+ fi
2484
+
2485
+ printf "%s" "${ttl_seconds}"
2486
+ }
2487
+
2488
+ installed_cache_fingerprint() {
2489
+ local manager="$1"
2490
+ local command_path=""
2491
+ local extra_token=""
2492
+
2493
+ case "${manager}" in
2494
+ apt)
2495
+ command_path="$(command -v dpkg-query 2>/dev/null || printf "missing")"
2496
+ ;;
2497
+ dnf)
2498
+ command_path="$(command -v dnf 2>/dev/null || printf "missing")"
2499
+ ;;
2500
+ pacman)
2501
+ command_path="$(command -v pacman 2>/dev/null || printf "missing")"
2502
+ ;;
2503
+ zypper)
2504
+ command_path="$(command -v zypper 2>/dev/null || printf "missing")"
2505
+ ;;
2506
+ emerge)
2507
+ if command_exists qlist; then
2508
+ command_path="$(command -v qlist 2>/dev/null || printf "missing")"
2509
+ extra_token="|mode=qlist"
2510
+ else
2511
+ command_path="/var/db/pkg"
2512
+ extra_token="|mode=vardb"
2513
+ fi
2514
+ ;;
2515
+ brew)
2516
+ command_path="$(command -v brew 2>/dev/null || printf "missing")"
2517
+ ;;
2518
+ winget)
2519
+ command_path="$(command -v winget 2>/dev/null || printf "missing")"
2520
+ ;;
2521
+ choco)
2522
+ command_path="$(command -v choco 2>/dev/null || printf "missing")"
2523
+ ;;
2524
+ scoop)
2525
+ command_path="$(command -v scoop 2>/dev/null || printf "missing")"
2526
+ ;;
2527
+ snap)
2528
+ command_path="$(command -v snap 2>/dev/null || printf "missing")"
2529
+ ;;
2530
+ flatpak)
2531
+ command_path="$(command -v flatpak 2>/dev/null || printf "missing")"
2532
+ ;;
2533
+ npm)
2534
+ command_path="$(command -v npm 2>/dev/null || printf "missing")"
2535
+ ;;
2536
+ bun)
2537
+ command_path="$(command -v bun 2>/dev/null || printf "missing")"
2538
+ if command_exists npm; then
2539
+ extra_token="|npm=$(command -v npm 2>/dev/null || printf "missing")"
2540
+ fi
2541
+ ;;
2542
+ *)
2543
+ command_path="unknown"
2544
+ ;;
2545
+ esac
2546
+
2547
+ printf "%s|cmd=%s%s" "$(cache_fingerprint "${manager}" "" "installed")" "${command_path}" "${extra_token}"
2548
+ }
2549
+
2244
2550
  manager_installed_names_cached() {
2245
2551
  local manager="$1"
2246
2552
  local output_file="$2"
2247
2553
  local cache_enabled="${FPF_DISABLE_INSTALLED_CACHE:-0}"
2554
+ local cache_ttl_seconds
2248
2555
  local cache_key
2249
2556
  local cache_file
2250
2557
  local cache_fingerprint_value
2558
+ local cached_fingerprint=""
2251
2559
 
2252
2560
  initialize_cache_root
2253
2561
 
2254
2562
  cache_key="$(cache_catalog_key "${manager}")"
2255
2563
  cache_file="$(cache_path_for_key "${cache_key}")"
2256
- cache_fingerprint_value="$(cache_fingerprint "${manager}" "" "installed")"
2564
+ cache_ttl_seconds="$(installed_cache_ttl_seconds)"
2565
+ cache_fingerprint_value="$(installed_cache_fingerprint "${manager}")"
2257
2566
 
2258
2567
  if [[ "${cache_enabled}" != "1" && -s "${cache_file}" ]]; then
2259
- cp "${cache_file}" "${output_file}"
2260
- return
2568
+ cached_fingerprint="$(cache_meta_value_for_key "${cache_key}" "fingerprint" 2>/dev/null || true)"
2569
+ if [[ "${cached_fingerprint}" == "${cache_fingerprint_value}" ]] && cache_is_fresh_with_ttl "${cache_key}" "${cache_ttl_seconds}"; then
2570
+ cp "${cache_file}" "${output_file}"
2571
+ return
2572
+ fi
2261
2573
  fi
2262
2574
 
2263
2575
  manager_installed_names "${manager}" >"${output_file}" 2>/dev/null || true
@@ -2544,24 +2856,26 @@ send_fzf_listen_action() {
2544
2856
  payload_size="$(printf "%s" "${action_payload}" | wc -c | tr -d '[:space:]')"
2545
2857
 
2546
2858
  if command_exists curl; then
2547
- curl --silent --show-error --fail --max-time 2 \
2859
+ if curl --silent --show-error --fail --max-time 2 \
2548
2860
  --request POST \
2549
2861
  --header 'Content-Type: text/plain' \
2550
2862
  --data-binary "${action_payload}" \
2551
- "http://${host}:${port}" >/dev/null 2>&1
2552
- return
2863
+ "http://${host}:${port}" >/dev/null 2>&1; then
2864
+ return 0
2865
+ fi
2553
2866
  fi
2554
2867
 
2555
2868
  if command_exists nc; then
2556
- {
2869
+ if {
2557
2870
  printf 'POST / HTTP/1.1\r\n'
2558
2871
  printf 'Host: %s:%s\r\n' "${host}" "${port}"
2559
2872
  printf 'Content-Type: text/plain\r\n'
2560
2873
  printf 'Content-Length: %s\r\n' "${payload_size}"
2561
2874
  printf '\r\n'
2562
2875
  printf '%s' "${action_payload}"
2563
- } | nc -w 2 "${host}" "${port}" >/dev/null 2>&1
2564
- return
2876
+ } | nc -w 2 "${host}" "${port}" >/dev/null 2>&1; then
2877
+ return 0
2878
+ fi
2565
2879
  fi
2566
2880
 
2567
2881
  if exec 9<>"/dev/tcp/${host}/${port}" 2>/dev/null; then
@@ -2653,265 +2967,49 @@ run_ipc_query_notify_action() {
2653
2967
  run_ipc_reload_action "${query}" || send_fzf_prompt_action "Search> " || true
2654
2968
  }
2655
2969
 
2970
+ manager_dispatch_action() {
2971
+ local manager="$1"
2972
+ local action="$2"
2973
+ shift 2 || true
2974
+ manager_execute_action "${manager}" "${action}" "$@"
2975
+ }
2976
+
2656
2977
  manager_install() {
2657
2978
  local manager="$1"
2658
2979
  shift
2659
-
2660
- case "${manager}" in
2661
- apt)
2662
- run_as_root apt-get install -y "$@"
2663
- ;;
2664
- dnf)
2665
- run_as_root dnf install -y "$@"
2666
- ;;
2667
- pacman)
2668
- run_as_root pacman -S --needed "$@"
2669
- ;;
2670
- zypper)
2671
- run_as_root zypper --non-interactive install --auto-agree-with-licenses "$@"
2672
- ;;
2673
- emerge)
2674
- run_as_root emerge --ask=n --verbose "$@"
2675
- ;;
2676
- brew)
2677
- brew install "$@"
2678
- ;;
2679
- winget)
2680
- local pkg
2681
- for pkg in "$@"; do
2682
- winget install --id "${pkg}" --exact --source winget --accept-package-agreements --accept-source-agreements --disable-interactivity
2683
- done
2684
- ;;
2685
- choco)
2686
- choco install "$@" -y
2687
- ;;
2688
- scoop)
2689
- scoop install "$@"
2690
- ;;
2691
- snap)
2692
- local pkg
2693
- for pkg in "$@"; do
2694
- run_as_root snap install "${pkg}" 2>/dev/null || run_as_root snap install --classic "${pkg}"
2695
- done
2696
- ;;
2697
- flatpak)
2698
- local pkg
2699
- for pkg in "$@"; do
2700
- flatpak install -y --user flathub "${pkg}" 2>/dev/null ||
2701
- flatpak install -y --user "${pkg}" 2>/dev/null ||
2702
- run_as_root flatpak install -y flathub "${pkg}" 2>/dev/null ||
2703
- run_as_root flatpak install -y "${pkg}"
2704
- done
2705
- ;;
2706
- npm)
2707
- npm install -g "$@"
2708
- ;;
2709
- bun)
2710
- bun add -g "$@"
2711
- ;;
2712
- esac
2980
+ manager_dispatch_action "${manager}" "install" "$@"
2713
2981
  }
2714
2982
 
2715
2983
  manager_remove() {
2716
2984
  local manager="$1"
2717
2985
  shift
2718
-
2719
- case "${manager}" in
2720
- apt)
2721
- run_as_root apt-get remove -y "$@"
2722
- ;;
2723
- dnf)
2724
- run_as_root dnf remove -y "$@"
2725
- ;;
2726
- pacman)
2727
- run_as_root pacman -Rsn "$@"
2728
- ;;
2729
- zypper)
2730
- run_as_root zypper --non-interactive remove "$@"
2731
- ;;
2732
- emerge)
2733
- run_as_root emerge --ask=n --deselect "$@"
2734
- run_as_root emerge --ask=n --depclean "$@"
2735
- ;;
2736
- brew)
2737
- brew uninstall "$@"
2738
- ;;
2739
- winget)
2740
- local pkg
2741
- for pkg in "$@"; do
2742
- winget uninstall --id "${pkg}" --exact --source winget --disable-interactivity
2743
- done
2744
- ;;
2745
- choco)
2746
- choco uninstall "$@" -y
2747
- ;;
2748
- scoop)
2749
- scoop uninstall "$@"
2750
- ;;
2751
- snap)
2752
- run_as_root snap remove "$@"
2753
- ;;
2754
- flatpak)
2755
- flatpak uninstall -y --user "$@" 2>/dev/null || run_as_root flatpak uninstall -y "$@"
2756
- ;;
2757
- npm)
2758
- npm uninstall -g "$@"
2759
- ;;
2760
- bun)
2761
- bun remove --global "$@"
2762
- ;;
2763
- esac
2986
+ manager_execute_action "${manager}" "remove" "$@"
2764
2987
  }
2765
2988
 
2766
2989
  manager_show_info() {
2767
2990
  local manager="$1"
2768
2991
  local package="$2"
2769
-
2770
- case "${manager}" in
2771
- apt)
2772
- cat <(apt-cache show "${package}" 2>/dev/null) <(printf "\n") <(dpkg -L "${package}" 2>/dev/null)
2773
- ;;
2774
- dnf)
2775
- cat <(dnf info "${package}" 2>/dev/null) <(printf "\n") <(rpm -ql "${package}" 2>/dev/null)
2776
- ;;
2777
- pacman)
2778
- cat <(pacman -Qi "${package}" 2>/dev/null || pacman -Si "${package}" 2>/dev/null) <(printf "\n") <(pacman -Ql "${package}" 2>/dev/null)
2779
- ;;
2780
- zypper)
2781
- zypper --non-interactive info "${package}" 2>/dev/null
2782
- ;;
2783
- emerge)
2784
- emerge --search --color=n "${package}" 2>/dev/null
2785
- ;;
2786
- brew)
2787
- brew info "${package}" 2>/dev/null
2788
- ;;
2789
- winget)
2790
- winget show --id "${package}" --exact --source winget --accept-source-agreements --disable-interactivity 2>/dev/null
2791
- ;;
2792
- choco)
2793
- choco info "${package}" 2>/dev/null
2794
- ;;
2795
- scoop)
2796
- scoop info "${package}" 2>/dev/null
2797
- ;;
2798
- snap)
2799
- snap info "${package}" 2>/dev/null
2800
- ;;
2801
- flatpak)
2802
- flatpak info "${package}" 2>/dev/null || flatpak remote-info flathub "${package}" 2>/dev/null
2803
- ;;
2804
- npm)
2805
- npm view "${package}" 2>/dev/null
2806
- ;;
2807
- bun)
2808
- bun info "${package}" 2>/dev/null || npm view "${package}" 2>/dev/null
2809
- ;;
2810
- esac
2992
+ manager_execute_action "${manager}" "show_info" "${package}"
2811
2993
  }
2812
2994
 
2813
2995
  manager_update() {
2814
2996
  local manager="$1"
2815
-
2816
- case "${manager}" in
2817
- apt)
2818
- run_as_root apt-get update
2819
- run_as_root apt-get upgrade -y
2820
- ;;
2821
- dnf)
2822
- run_as_root dnf upgrade -y
2823
- ;;
2824
- pacman)
2825
- run_as_root pacman -Syu
2826
- ;;
2827
- zypper)
2828
- run_as_root zypper --non-interactive refresh
2829
- run_as_root zypper --non-interactive update
2830
- ;;
2831
- emerge)
2832
- run_as_root emerge --sync
2833
- run_as_root emerge --ask=n --update --deep --newuse @world
2834
- ;;
2835
- brew)
2836
- brew update
2837
- brew upgrade
2838
- ;;
2839
- winget)
2840
- winget upgrade --all --source winget --accept-package-agreements --accept-source-agreements --disable-interactivity
2841
- ;;
2842
- choco)
2843
- choco upgrade all -y
2844
- ;;
2845
- scoop)
2846
- scoop update
2847
- scoop update "*"
2848
- ;;
2849
- snap)
2850
- run_as_root snap refresh
2851
- ;;
2852
- flatpak)
2853
- flatpak update -y --user 2>/dev/null || run_as_root flatpak update -y
2854
- ;;
2855
- npm)
2856
- npm update -g
2857
- ;;
2858
- bun)
2859
- bun update --global
2860
- ;;
2861
- esac
2997
+ manager_execute_action "${manager}" "update"
2862
2998
  }
2863
2999
 
2864
3000
  manager_refresh() {
2865
3001
  local manager="$1"
2866
-
2867
- case "${manager}" in
2868
- apt)
2869
- run_as_root apt-get update
2870
- ;;
2871
- dnf)
2872
- run_as_root dnf makecache
2873
- ;;
2874
- pacman)
2875
- run_as_root pacman -Sy
2876
- ;;
2877
- zypper)
2878
- run_as_root zypper --non-interactive refresh
2879
- ;;
2880
- emerge)
2881
- run_as_root emerge --sync
2882
- ;;
2883
- brew)
2884
- brew update
2885
- ;;
2886
- winget)
2887
- winget source update --name winget --accept-source-agreements --disable-interactivity
2888
- ;;
2889
- choco)
2890
- choco source list --limit-output >/dev/null
2891
- ;;
2892
- scoop)
2893
- scoop update
2894
- ;;
2895
- snap)
2896
- run_as_root snap refresh --list
2897
- ;;
2898
- flatpak)
2899
- ensure_flatpak_flathub_remote >/dev/null 2>&1 || true
2900
- flatpak update -y --appstream --user 2>/dev/null || run_as_root flatpak update -y --appstream
2901
- ;;
2902
- npm)
2903
- npm cache verify
2904
- ;;
2905
- bun)
2906
- bun pm cache >/dev/null
2907
- ;;
2908
- esac
3002
+ manager_execute_action "${manager}" "refresh"
2909
3003
  }
2910
3004
 
2911
3005
  confirm_action() {
2912
3006
  local prompt="$1"
2913
3007
  local reply=""
2914
3008
 
3009
+ if assume_yes_enabled; then
3010
+ return 0
3011
+ fi
3012
+
2915
3013
  printf "%s [y/N]: " "${prompt}" >&2
2916
3014
  read -r reply || true
2917
3015
 
@@ -2932,6 +3030,9 @@ run_fuzzy_selector() {
2932
3030
  local reload_cmd="${4:-}"
2933
3031
  local reload_ipc_cmd="${5:-}"
2934
3032
  local script_path="${BASH_SOURCE[0]}"
3033
+ local quoted_script_path=""
3034
+ local quoted_help_file=""
3035
+ local quoted_kbinds_file=""
2935
3036
  local preview_cmd
2936
3037
  local fzf_shell
2937
3038
 
@@ -2939,7 +3040,11 @@ run_fuzzy_selector() {
2939
3040
  script_path="$(pwd)/${script_path}"
2940
3041
  fi
2941
3042
 
2942
- preview_cmd="FPF_SESSION_TMP_ROOT=$(printf '%q' "${SESSION_TMP_ROOT}") ${script_path} --preview-item --manager {1} -- {2}"
3043
+ printf -v quoted_script_path "%q" "${script_path}"
3044
+ printf -v quoted_help_file "%q" "${HELP_FILE}"
3045
+ printf -v quoted_kbinds_file "%q" "${KBINDS_FILE}"
3046
+
3047
+ preview_cmd="FPF_SESSION_TMP_ROOT=$(printf '%q' "${SESSION_TMP_ROOT}") ${quoted_script_path} --preview-item --manager {1} -- {2}"
2943
3048
  if command_exists bash; then
2944
3049
  fzf_shell="bash"
2945
3050
  else
@@ -2961,8 +3066,8 @@ run_fuzzy_selector() {
2961
3066
  --margin="2%,1%,2%,1%" \
2962
3067
  --cycle \
2963
3068
  --tiebreak=begin,chunk,length \
2964
- --bind=ctrl-k:preview:"cat ${KBINDS_FILE}" \
2965
- --bind=ctrl-h:preview:"cat ${HELP_FILE}" \
3069
+ --bind="ctrl-k:preview:cat ${quoted_kbinds_file}" \
3070
+ --bind="ctrl-h:preview:cat ${quoted_help_file}" \
2966
3071
  --bind='ctrl-/:change-preview-window(hidden|)' \
2967
3072
  --bind=ctrl-n:next-selected,ctrl-b:prev-selected \
2968
3073
  --bind='focus:transform-preview-label:echo [{1}] {2}')
@@ -2999,6 +3104,7 @@ run_fuzzy_selector() {
2999
3104
  main() {
3000
3105
  ensure_tmp_root
3001
3106
  initialize_session_tmp_root
3107
+ load_fpf_libraries
3002
3108
  if [[ -z "${FPF_SESSION_TMP_ROOT:-}" ]]; then
3003
3109
  trap cleanup_session_tmp_root EXIT
3004
3110
  fi
package/fpf.png ADDED
Binary file
@@ -0,0 +1,330 @@
1
+ manager_execute_action() {
2
+ local manager="$1"
3
+ local action="$2"
4
+ shift 2
5
+ local package=""
6
+ local pkg=""
7
+
8
+ case "${manager}" in
9
+ apt)
10
+ case "${action}" in
11
+ install)
12
+ run_as_root apt-get install -y "$@"
13
+ ;;
14
+ remove)
15
+ run_as_root apt-get remove -y "$@"
16
+ ;;
17
+ show_info)
18
+ package="${1:-}"
19
+ cat <(apt-cache show "${package}" 2>/dev/null) <(printf "\n") <(dpkg -L "${package}" 2>/dev/null)
20
+ ;;
21
+ update)
22
+ run_as_root apt-get update
23
+ run_as_root apt-get upgrade -y
24
+ ;;
25
+ refresh)
26
+ run_as_root apt-get update
27
+ ;;
28
+ *)
29
+ return 1
30
+ ;;
31
+ esac
32
+ ;;
33
+ dnf)
34
+ case "${action}" in
35
+ install)
36
+ run_as_root dnf install -y "$@"
37
+ ;;
38
+ remove)
39
+ run_as_root dnf remove -y "$@"
40
+ ;;
41
+ show_info)
42
+ package="${1:-}"
43
+ cat <(dnf info "${package}" 2>/dev/null) <(printf "\n") <(rpm -ql "${package}" 2>/dev/null)
44
+ ;;
45
+ update)
46
+ run_as_root dnf upgrade -y
47
+ ;;
48
+ refresh)
49
+ run_as_root dnf makecache
50
+ ;;
51
+ *)
52
+ return 1
53
+ ;;
54
+ esac
55
+ ;;
56
+ pacman)
57
+ case "${action}" in
58
+ install)
59
+ run_as_root pacman -S --needed "$@"
60
+ ;;
61
+ remove)
62
+ run_as_root pacman -Rsn "$@"
63
+ ;;
64
+ show_info)
65
+ package="${1:-}"
66
+ cat <(pacman -Qi "${package}" 2>/dev/null || pacman -Si "${package}" 2>/dev/null) <(printf "\n") <(pacman -Ql "${package}" 2>/dev/null)
67
+ ;;
68
+ update)
69
+ run_as_root pacman -Syu
70
+ ;;
71
+ refresh)
72
+ run_as_root pacman -Sy
73
+ ;;
74
+ *)
75
+ return 1
76
+ ;;
77
+ esac
78
+ ;;
79
+ zypper)
80
+ case "${action}" in
81
+ install)
82
+ run_as_root zypper --non-interactive install --auto-agree-with-licenses "$@"
83
+ ;;
84
+ remove)
85
+ run_as_root zypper --non-interactive remove "$@"
86
+ ;;
87
+ show_info)
88
+ package="${1:-}"
89
+ zypper --non-interactive info "${package}" 2>/dev/null
90
+ ;;
91
+ update)
92
+ run_as_root zypper --non-interactive refresh
93
+ run_as_root zypper --non-interactive update
94
+ ;;
95
+ refresh)
96
+ run_as_root zypper --non-interactive refresh
97
+ ;;
98
+ *)
99
+ return 1
100
+ ;;
101
+ esac
102
+ ;;
103
+ emerge)
104
+ case "${action}" in
105
+ install)
106
+ run_as_root emerge --ask=n --verbose "$@"
107
+ ;;
108
+ remove)
109
+ run_as_root emerge --ask=n --deselect "$@"
110
+ run_as_root emerge --ask=n --depclean "$@"
111
+ ;;
112
+ show_info)
113
+ package="${1:-}"
114
+ emerge --search --color=n "${package}" 2>/dev/null
115
+ ;;
116
+ update)
117
+ run_as_root emerge --sync
118
+ run_as_root emerge --ask=n --update --deep --newuse @world
119
+ ;;
120
+ refresh)
121
+ run_as_root emerge --sync
122
+ ;;
123
+ *)
124
+ return 1
125
+ ;;
126
+ esac
127
+ ;;
128
+ brew)
129
+ case "${action}" in
130
+ install)
131
+ brew install "$@"
132
+ ;;
133
+ remove)
134
+ brew uninstall "$@"
135
+ ;;
136
+ show_info)
137
+ package="${1:-}"
138
+ brew info "${package}" 2>/dev/null
139
+ ;;
140
+ update)
141
+ brew update
142
+ brew upgrade
143
+ ;;
144
+ refresh)
145
+ brew update
146
+ ;;
147
+ *)
148
+ return 1
149
+ ;;
150
+ esac
151
+ ;;
152
+ winget)
153
+ case "${action}" in
154
+ install)
155
+ for pkg in "$@"; do
156
+ winget install --id "${pkg}" --exact --source winget --accept-package-agreements --accept-source-agreements --disable-interactivity
157
+ done
158
+ ;;
159
+ remove)
160
+ for pkg in "$@"; do
161
+ winget uninstall --id "${pkg}" --exact --source winget --disable-interactivity
162
+ done
163
+ ;;
164
+ show_info)
165
+ package="${1:-}"
166
+ winget show --id "${package}" --exact --source winget --accept-source-agreements --disable-interactivity 2>/dev/null
167
+ ;;
168
+ update)
169
+ winget upgrade --all --source winget --accept-package-agreements --accept-source-agreements --disable-interactivity
170
+ ;;
171
+ refresh)
172
+ winget source update --name winget --accept-source-agreements --disable-interactivity
173
+ ;;
174
+ *)
175
+ return 1
176
+ ;;
177
+ esac
178
+ ;;
179
+ choco)
180
+ case "${action}" in
181
+ install)
182
+ choco install "$@" -y
183
+ ;;
184
+ remove)
185
+ choco uninstall "$@" -y
186
+ ;;
187
+ show_info)
188
+ package="${1:-}"
189
+ choco info "${package}" 2>/dev/null
190
+ ;;
191
+ update)
192
+ choco upgrade all -y
193
+ ;;
194
+ refresh)
195
+ choco source list --limit-output >/dev/null
196
+ ;;
197
+ *)
198
+ return 1
199
+ ;;
200
+ esac
201
+ ;;
202
+ scoop)
203
+ case "${action}" in
204
+ install)
205
+ scoop install "$@"
206
+ ;;
207
+ remove)
208
+ scoop uninstall "$@"
209
+ ;;
210
+ show_info)
211
+ package="${1:-}"
212
+ scoop info "${package}" 2>/dev/null
213
+ ;;
214
+ update)
215
+ scoop update
216
+ scoop update "*"
217
+ ;;
218
+ refresh)
219
+ scoop update
220
+ ;;
221
+ *)
222
+ return 1
223
+ ;;
224
+ esac
225
+ ;;
226
+ snap)
227
+ case "${action}" in
228
+ install)
229
+ for pkg in "$@"; do
230
+ run_as_root snap install "${pkg}" 2>/dev/null || run_as_root snap install --classic "${pkg}"
231
+ done
232
+ ;;
233
+ remove)
234
+ run_as_root snap remove "$@"
235
+ ;;
236
+ show_info)
237
+ package="${1:-}"
238
+ snap info "${package}" 2>/dev/null
239
+ ;;
240
+ update)
241
+ run_as_root snap refresh
242
+ ;;
243
+ refresh)
244
+ run_as_root snap refresh --list
245
+ ;;
246
+ *)
247
+ return 1
248
+ ;;
249
+ esac
250
+ ;;
251
+ flatpak)
252
+ case "${action}" in
253
+ install)
254
+ for pkg in "$@"; do
255
+ flatpak install -y --user flathub "${pkg}" 2>/dev/null ||
256
+ flatpak install -y --user "${pkg}" 2>/dev/null ||
257
+ run_as_root flatpak install -y flathub "${pkg}" 2>/dev/null ||
258
+ run_as_root flatpak install -y "${pkg}"
259
+ done
260
+ ;;
261
+ remove)
262
+ flatpak uninstall -y --user "$@" 2>/dev/null || run_as_root flatpak uninstall -y "$@"
263
+ ;;
264
+ show_info)
265
+ package="${1:-}"
266
+ flatpak info "${package}" 2>/dev/null || flatpak remote-info flathub "${package}" 2>/dev/null
267
+ ;;
268
+ update)
269
+ flatpak update -y --user 2>/dev/null || run_as_root flatpak update -y
270
+ ;;
271
+ refresh)
272
+ ensure_flatpak_flathub_remote >/dev/null 2>&1 || true
273
+ flatpak update -y --appstream --user 2>/dev/null || run_as_root flatpak update -y --appstream
274
+ ;;
275
+ *)
276
+ return 1
277
+ ;;
278
+ esac
279
+ ;;
280
+ npm)
281
+ case "${action}" in
282
+ install)
283
+ npm install -g "$@"
284
+ ;;
285
+ remove)
286
+ npm uninstall -g "$@"
287
+ ;;
288
+ show_info)
289
+ package="${1:-}"
290
+ npm view "${package}" 2>/dev/null
291
+ ;;
292
+ update)
293
+ npm update -g
294
+ ;;
295
+ refresh)
296
+ npm cache verify
297
+ ;;
298
+ *)
299
+ return 1
300
+ ;;
301
+ esac
302
+ ;;
303
+ bun)
304
+ case "${action}" in
305
+ install)
306
+ bun add -g "$@"
307
+ ;;
308
+ remove)
309
+ bun remove --global "$@"
310
+ ;;
311
+ show_info)
312
+ package="${1:-}"
313
+ bun info "${package}" 2>/dev/null || npm view "${package}" 2>/dev/null
314
+ ;;
315
+ update)
316
+ bun update --global
317
+ ;;
318
+ refresh)
319
+ bun pm cache >/dev/null
320
+ ;;
321
+ *)
322
+ return 1
323
+ ;;
324
+ esac
325
+ ;;
326
+ *)
327
+ return 1
328
+ ;;
329
+ esac
330
+ }
package/package.json CHANGED
@@ -1,14 +1,16 @@
1
1
  {
2
2
  "name": "fpf-cli",
3
- "version": "1.6.29",
3
+ "version": "1.6.31",
4
4
  "description": "Cross-platform fuzzy package finder powered by fzf",
5
5
  "bin": {
6
6
  "fpf": "fpf"
7
7
  },
8
8
  "files": [
9
9
  "fpf",
10
+ "lib/fpf/*.sh",
10
11
  "README.md",
11
- "LICENSE"
12
+ "LICENSE",
13
+ "fpf.png"
12
14
  ],
13
15
  "keywords": [
14
16
  "fzf",