Skip to main content

Bunnify

PyPI version Python 3.14+ License: MIT CI

A Python bookmark manager and URL shortcut system: terminal CLI, web command palette, Chrome OpenSearch integration, and parameterized redirects.

Install

pipx is the recommended path for end users:

pipx install bunnify
pipx ensurepath   # adds ~/.local/bin to PATH if needed (restart the shell)
bunnify --version
bunnify onboard   # print bookmarks / setup / Chrome next steps

pipx installs bunnify and bunnify-server under ~/.local/bin by default (or $PIPX_BIN_DIR when set). Ensure that directory is on your PATH before running either command. Prefer the pipx apps over any checkout ./scripts/bunnify still on PATH.

The wheel installs bunnify (CLI), bunnify-server (Django server), and spotty-bunny (macOS search box; needs extra macos). No repository checkout or uv is required at runtime.

Package on PyPI: pypi.org/project/bunnify.

After install or upgrade

pipx does not print package docs after install. Run:

bunnify onboard

That prints the ready-to-go checklist (bookmarks path, bunnify setup, Chrome/Edge, and upgrade). Same text:

bunnify --onboard

Summary of what it covers:

  1. Bookmarks at ~/.config/bunnify/bookmarks.json (required before the server starts) — bunnify setup can install the example shortcuts, or seed from bunnify.json.example
  2. bunnify setup — local on a laptop; remote for a home/always-on host
    LOCAL.md
  3. Chrome / Edge — match BUNNIFY_BASE_URL from config.env
    CHROME_SETUP.md
  4. Try it: bunnify gh or address-bar keyword (e.g. b gh)
  5. macOS Spotty Bunny (optional) — pipx install 'bunnify[macos]' then bunnify spotty-bunny install (LOCAL.md)

Upgrade

Preferred:

bunnify upgrade

That prints the version/commit you are running from, the PyPI target, then the pipx app version/commit to after pipx upgrade. Use this instead of bare pipx upgrade bunnify so you can see when PATH is still a git checkout.

pipx upgrade only updates ~/.local/bin/bunnify. If bunnify --version still shows a checkout SHA, PATH is hitting ./scripts/bunnify or a repo .venv. After pipx ensurepath, command -v bunnify should be ~/.local/bin/bunnify.

Bookmarks and ~/.config/bunnify/config.env are user data — upgrades do not overwrite them. After a major server change, re-run bunnify setup only if docs or release notes say so. Setup will offer to stop a different local Bunnify build and start this CLI's build when the port is already in use.

Source and docs: github.com/the-hcma/bunnify.

Quick start

1. Bookmarks file

bunnify setup offers to install the example bookmarks when none exist yet. You can also create the file yourself from the documented example into XDG config:

mkdir -p ~/.config/bunnify
curl -fsSL https://raw.githubusercontent.com/the-hcma/bunnify/main/bunnify.json.example \
  -o ~/.config/bunnify/bookmarks.json
# edit ~/.config/bunnify/bookmarks.json with your shortcuts

See Configuration for overrides (BUNNIFY_BOOKMARKS, XDG_CONFIG_HOME).

2. Configure local or remote mode

bunnify setup

Laptop / daily machine: choose local (default). Setup starts a managed server, verifies /health, records the port, and saves settings to ~/.config/bunnify/config.env. Point Chrome or Edge at the same BUNNIFY_BASE_URL (Chrome / Edge setup).

Home server / always-on host: choose remote on client devices and enter that host’s URL. Prefer a centralized remote install when several machines share one server — not as a laptop’s only dependency if you often go offline.

One-time override without saving: bunnify --base-url https://… shortcut.

Details: Local and remote setup.

3. Run shortcuts

bunnify              # interactive REPL (Tab completion, history)
bunnify gh           # open a shortcut in the browser
bunnify bun          # Bunnify source on GitHub
bunnify pr the-hcma/bunnify 272   # parameterized shortcut
bunnify --fzf        # fuzzy picker
bunnify --print-url gh

Unknown keys exit non-zero in direct mode (no search-engine fallback).

Features

  • CLI / REPL — fuzzy Tab completion, fzf mode, Vim/Emacs edit keys
  • Spotty Bunny — dual-Control search box (spotty-bunny; extra macos; login LaunchAgent via install / upgrade / uninstall)
  • Web/cmd/ command palette, /list/ browser, smart /search/
  • Chrome / Edge — OpenSearch at /opensearch.xml (setup guide)
  • Parameters — URLs with #{name} placeholders and optional defaults
  • Validation — JSON Schema on load; reserved keys h / help

Spotty Bunny (macOS)

Optional Spotlight-style search box. Hold one Control and tap the other to type a shortcut. Needs the macos extra (PyObjC).

Install

pipx install 'bunnify[macos]'
pipx ensurepath
bunnify spotty-bunny install    # login LaunchAgent (TCC + KeepAlive)
bunnify spotty-bunny status

install grants Accessibility and Input Monitoring to the interpreter launchd will exec (typically the pipx venv Python), writes ~/Library/LaunchAgents/com.thehcma.bunnify.spotty-bunny.plist, and bootstraps it. Bare spotty-bunny (or bunnify spotty-bunny with no subcommand) still runs in the foreground for debugging.

Upgrade

bunnify upgrade                 # pipx package
bunnify spotty-bunny upgrade    # refresh the LaunchAgent binary path

Run upgrade after bunnify upgrade so launchd does not keep a stale ProgramArguments path.

Uninstall

bunnify spotty-bunny uninstall

That boots the agent out, removes the plist, and stops a leftover overlay process. Bookmarks and config.env are unchanged. Right-click the bunny icon for Install Spotty Bunny (when the LaunchAgent is missing), Quit Spotty Bunny, Uninstall Spotty Bunny, and (when installed and a newer PyPI version is known) Upgrade Spotty Bunny. An up-arrow badge on the icon and an About line mark an outdated install (PyPI is checked at most once a day).

Left-click the bunny for About: bookmarks file, GitHub repo when that file lives in a GitHub checkout, and whether the CLI is talking to a local or remote server (with its URL).

Details: Local and remote setup.

Server lifecycle

Installed users manage the server with bunnify-server:

bunnify-server --help
# Foreground (systemd, LaunchAgent, debugging):
bunnify-server --foreground --noninteractive --port 8000
# Background managed daemon (returns after fork):
bunnify-server --port 8000 --noninteractive --pid-dir ~/.local/share/bunnify/run
bunnify-server --stop --pid-dir ~/.local/share/bunnify/run
curl --max-time 2 http://127.0.0.1:8000/health

bunnify setup starts a managed local server for daily CLI use. Stop it with:

bunnify stop

That prints the URL and runtime directory before stopping. Details: Local and remote setup.

Linux production: systemd user service via setup-service from repository-helpers.

macOS: LaunchAgent example.

Web usage

With the server running (default http://127.0.0.1:8000 after setup):

URL Purpose
/cmd/ Command palette (recommended)
/search/?q=pr+12345 Smart search
/list/ Browse all bookmarks
/<key>/ Direct redirect
/opensearch.xml Chrome search engine descriptor

Bookmarks format

{
  "gh": {
    "description": "GitHub",
    "url": "https://github.com/"
  },
  "pr": {
    "description": "Pull request",
    "url": "https://github.com/#{repo}/pull/#{pr_number}",
    "defaults": { "repo": "org/repo" }
  }
}

Required fields: description, url. Placeholders use #{parameter_name}. Reload after edits: the server watches the JSON file, or run load_bookmarks in a development checkout.

Development checkout

Contributors clone the repo and use uv — separate from the pipx path above.

git clone https://github.com/the-hcma/bunnify.git
cd bunnify
uv sync
uv run python manage.py migrate

mkdir -p ~/.config/bunnify
cp bunnify.json.example ~/.config/bunnify/bookmarks.json

./scripts/bunnify setup
./scripts/bunnify-server --console --log-level DEBUG   # optional
./test_bunnify

Full guidelines: CONTRIBUTING.md. Quality gates: ./scripts/checks.

Wrappers under ./scripts/ prefer uv run when uv is on PATH, otherwise the checkout .venv (same entry points systemd uses on service hosts).

Documentation

Doc Audience
CONFIG.md XDG paths and environment variables
LOCAL.md Local vs remote setup, ports, Spotty Bunny
SYSTEMD.md Linux user service
CHROME_SETUP.md Browser search engine
QUICK_REFERENCE.md Cheat sheet
RELEASING.md Maintainers: PyPI releases

Troubleshooting

Server won't start

bunnify-server --console --log-level DEBUG
# or in a checkout: ./scripts/bunnify-server --console

Bookmarks missing

ls -l ~/.config/bunnify/bookmarks.json
# run `bunnify setup` (offers the example), or copy bunnify.json.example

CLI can't reach server

bunnify setup
curl -sf "$(grep BUNNIFY_BASE_URL ~/.config/bunnify/config.env | cut -d= -f2-)/health"

Stale managed process

bunnify-server --stop --pid-dir ~/.local/share/bunnify/run

Releasing

Maintainers: docs/RELEASING.md (Release Please + PyPI).

License

MIT © 2026 Henrique Andrade (GitHub's thehcma) — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bunnify-0.7.1.tar.gz (137.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bunnify-0.7.1-py3-none-any.whl (161.9 kB view details)

Uploaded Python 3

File details

Details for the file bunnify-0.7.1.tar.gz.

File metadata

  • Download URL: bunnify-0.7.1.tar.gz
  • Upload date:
  • Size: 137.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for bunnify-0.7.1.tar.gz
Algorithm Hash digest
SHA256 f2b76e0a4df24288c6741213d2d7e17f5df8d8d67747c31e51fbc6e851a1650d
MD5 939eb78ea5eaa30d6d1baa27766cf5bc
BLAKE2b-256 98e3c0064521d54281007831be9be633e06af58b3b9c95f2cb582342cae64148

See more details on using hashes here.

Provenance

The following attestation bundles were made for bunnify-0.7.1.tar.gz:

Publisher: release-please.yml on the-hcma/bunnify

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file bunnify-0.7.1-py3-none-any.whl.

File metadata

  • Download URL: bunnify-0.7.1-py3-none-any.whl
  • Upload date:
  • Size: 161.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for bunnify-0.7.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f942cdc2484501dea58705eb1fc2eb77887d86bec34ec9db894b1dea7b2eb599
MD5 7c045a2737d20c2b344699dae82f0f16
BLAKE2b-256 e5bca4b6531b06cab2eb087b86320a13252d8393be4d23c22e93ff5843a4b916

See more details on using hashes here.

Provenance

The following attestation bundles were made for bunnify-0.7.1-py3-none-any.whl:

Publisher: release-please.yml on the-hcma/bunnify

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.12.1

2 files

0.12.0

2 files

0.11.3

2 files

0.11.2

2 files

0.11.1

2 files

0.11.0

2 files

0.10.0

2 files

0.9.2

2 files

0.9.1

2 files

0.9.0

2 files

0.8.3

2 files

0.8.1

2 files

0.8.0

2 files

This release

0.7.1 This release

2 files

0.7.0

2 files

0.6.1

2 files

0.6.0

2 files

0.5.0

2 files

0.4.0

2 files

0.3.0

2 files

0.2.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page