{"_id":"@agileguy/nitfy","name":"@agileguy/nitfy","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@agileguy/nitfy","version":"1.0.0","description":"ntfy CLI client — messages, send, unread, read, watch, health, topics, completions. Zero dependencies, runs with bun.","type":"module","main":"dist/ntfy.js","bin":{"nitfy":"dist/ntfy.js"},"scripts":{"dev":"bun run ntfy.ts","test":"bun test","build":"bun build ntfy.ts --outdir dist --target node --format esm","build:binary":"bun build --compile ntfy.ts --outfile ntfy","type-check":"bunx tsc --noEmit","clean":"rm -rf dist","prepublishOnly":"bun run clean && bun run build"},"engines":{"bun":">=1.0.0","node":">=18.0.0"},"keywords":["ntfy","notifications","push","cli","devops","sre"],"author":{"name":"agileguy"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/agileguy/nitfy.git"},"homepage":"https://github.com/agileguy/nitfy#readme","bugs":{"url":"https://github.com/agileguy/nitfy/issues"},"devDependencies":{"bun-types":"^1.3.9"},"_id":"@agileguy/nitfy@1.0.0","gitHead":"a0666b9f9b33b690ace77ac9f7dbc4ddea0f7aa0","_nodeVersion":"20.20.0","_npmVersion":"10.8.2","dist":{"integrity":"sha512-54GV9tfuulJab+U3UY0fWNTIr08USdMkLmyC+mNjSILpylUuBQS4QXd3lcVMHV5zn70mj8qMOUkSXy3LJ/Ep3Q==","shasum":"133cb35ab3b2bf06aec3a4396c2cdd80ff2f262a","tarball":"https://registry.npmjs.org/@agileguy/nitfy/-/nitfy-1.0.0.tgz","fileCount":5,"unpackedSize":88812,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIHcNjlY4t3jB8phI3tXU7BS5A7NKidSNfAa3AXkDmQrTAiAIQ4pqED2nfrMKYVOxIaFlK+eXgqRmRIgkQal1JtvlSw=="}]},"_npmUser":{"name":"agileguy","email":"agile.guy@hotmail.com"},"directories":{},"maintainers":[{"name":"agileguy","email":"agile.guy@hotmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/nitfy_1.0.0_1771699189704_0.7675640885239525"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-21T18:39:49.636Z","1.0.0":"2026-02-21T18:39:49.854Z","modified":"2026-02-21T18:39:50.108Z"},"maintainers":[{"name":"agileguy","email":"agile.guy@hotmail.com"}],"description":"ntfy CLI client — messages, send, unread, read, watch, health, topics, completions. Zero dependencies, runs with bun.","homepage":"https://github.com/agileguy/nitfy#readme","keywords":["ntfy","notifications","push","cli","devops","sre"],"repository":{"type":"git","url":"git+https://github.com/agileguy/nitfy.git"},"author":{"name":"agileguy"},"bugs":{"url":"https://github.com/agileguy/nitfy/issues"},"license":"MIT","readme":"# nitfy\n\nA fast, zero-dependency CLI client for [ntfy](https://ntfy.sh) - the simple HTTP push notification service.\n\nWorks with self-hosted ntfy servers and ntfy.sh. Supports named profiles, topic groups, watch mode with audio alerts, and shell completions.\n\n## Installation\n\n### Run with Bun (no build step)\n\n```bash\ngit clone https://github.com/agileguy/nitfy\ncd nitfy\nbun install\nbun run ntfy.ts messages\n```\n\nAdd a shell alias for convenience:\n\n```bash\nalias ntfy='bun run /path/to/nitfy/ntfy.ts'\n```\n\n### Compile to a standalone binary\n\nRequires Bun 1.0+. The compiled binary runs without Bun installed.\n\n```bash\nbun run build\n# produces: ./ntfy\ncp ntfy /usr/local/bin/\n```\n\nThe `ntfy` binary is excluded from version control via `.gitignore`.\n\n## Quick Start\n\n### Option A: Environment variables (simplest)\n\nSet these in your shell profile (`~/.bashrc`, `~/.zshrc`, or `~/.profile`):\n\n```bash\nexport NTFY_URL=https://ntfy.sh\nexport NTFY_TOPIC=my-alerts\nexport NTFY_USER=alice          # optional for private topics\nexport NTFY_PASSWORD=secret     # optional for private topics\n```\n\nThen use the CLI immediately:\n\n```bash\nntfy messages\nntfy send \"Hello from ntfy\"\nntfy health\n```\n\n### Option B: Named profiles (recommended)\n\nCreate a named profile for persistent, multi-server configuration:\n\n```bash\nntfy config add home \\\n  --url https://ntfy.example.com \\\n  --user alice \\\n  --password secret \\\n  --topic alerts\n```\n\nThe first profile added becomes the active profile automatically.\n\n## Configuration\n\nConfiguration is stored at `~/.config/ntfy-cli/config.json` (mode 0600). State (last-read timestamps) is stored at `~/.config/ntfy-cli/state.json`.\n\n### Profile commands\n\n```bash\n# Add a profile\nntfy config add <name> --url <url> [--user <user>] [--password <pass>] --topic <topic>\n\n# List all profiles\nntfy config list\n\n# Switch active profile\nntfy config use <name>\n\n# Show active profile (password masked)\nntfy config show\n\n# Remove a profile\nntfy config remove <name>\n```\n\n### Example: multiple servers\n\n```bash\nntfy config add home \\\n  --url https://ntfy.home.example.com \\\n  --user dan \\\n  --password s3cr3t \\\n  --topic alerts\n\nntfy config add work \\\n  --url https://ntfy.sh \\\n  --user work-user \\\n  --password work-pass \\\n  --topic work-alerts\n\nntfy config add public --url https://ntfy.sh --topic public-announcements\n\n# Use work by default\nntfy config use work\n\n# Override per-command\nntfy messages --server home\nntfy send \"Deploy done\" --server work\n```\n\n## Commands Reference\n\nAll commands support `--server <name>` to override the active profile, `--json` for machine-readable output, `--no-color` to strip ANSI codes, and `--quiet` / `-q` to suppress decorative output.\n\n### messages / msg\n\nFetch and display messages for a topic.\n\n```bash\nntfy messages\nntfy messages --topic alerts\nntfy messages --since 6h\nntfy messages --since 24h --priority high\nntfy messages --limit 10\nntfy messages --json\nntfy msg --topic alerts --since 1h --limit 5\n```\n\nFlags:\n- `--topic / -t <topic>` - Topic to fetch (defaults to profile defaultTopic)\n- `--since / -s <duration>` - How far back to fetch: `1h`, `6h`, `24h`, `2d`, `7d`, `all` (default: `12h`)\n- `--priority <level>` - Filter to messages at or above priority level (1-5 or min/low/default/high/urgent)\n- `--limit <n>` - Show only the most recent N messages\n\n### all\n\nAlias that fetches the `FAST-all` topic if present in the profile, otherwise the first configured topic.\n\n```bash\nntfy all\nntfy all --since 2h\n```\n\n### unread\n\nShow messages received since the last time `ntfy read` was run, across all watched topics.\n\n```bash\nntfy unread\nntfy unread --topic alerts\nntfy unread --since 6h\nntfy unread --json\nntfy unread --count          # print integer count for single topic\nntfy unread --total          # print total count across all topics\n```\n\nFlags:\n- `--topic <topic>` - Check only this topic\n- `--since <duration>` - Override since period (ignores last-read timestamp)\n- `--count` - Print count as plain integer (per topic or total)\n- `--total` - Print total count across all topics as integer\n\n### send\n\nSend a notification message to a topic.\n\n```bash\nntfy send \"Backup completed\"\nntfy send \"Deploy failed\" --title \"CI Alert\" --priority urgent\nntfy send \"Weekly report\" --topic reports --tags \"report,weekly\"\nntfy send \"Reminder\" --delay 30m\nntfy send \"Click me\" --click https://example.com\nntfy send \"**Bold** text\" --markdown\n```\n\nFlags:\n- `--topic / -t <topic>` - Destination topic (defaults to profile defaultTopic)\n- `--title <title>` - Notification title\n- `--priority / -p <level>` - Priority: `1`-`5` or `min`, `low`, `default`, `high`, `urgent`\n- `--tags <tags>` - Comma-separated tags (displayed as emoji on mobile)\n- `--delay <duration>` - Schedule delivery: `30s`, `1m`, `5m`, `30m`, `1h`, `3h`, `12h`\n- `--click <url>` - URL to open when notification is tapped\n- `--attach <url>` - URL of an attachment\n- `--markdown / --md` - Render message body as Markdown\n\n### read\n\nMark topic(s) as read by updating the last-read timestamp. Affects what `ntfy unread` shows next time.\n\n```bash\nntfy read                    # mark all profile topics as read\nntfy read --topic alerts     # mark only one topic\nntfy read --all              # mark all topics on all profiles\n```\n\n### unread workflow example\n\n```bash\nntfy unread         # see what's new\nntfy read           # mark all as read\nntfy unread         # now shows 0\n```\n\n### watch\n\nPoll topics for new messages in real time and play an audio alert on arrival. Press Ctrl+C to stop and see a session summary.\n\n```bash\nntfy watch\nntfy watch --topic alerts\nntfy watch --group critical       # watch a named topic group\nntfy watch --interval 30          # poll every 30 seconds (default: 60)\nntfy watch --no-sound             # disable audio\nntfy watch --sound /path/to/ping.wav\nntfy watch --device \"Built-in Output\"   # macOS audio device\nntfy watch --priority high        # only play sound for high+ priority\n```\n\nFlags:\n- `--topic / -t <topic>` - Watch a specific topic\n- `--group <name>` - Watch a named topic group\n- `--interval <seconds>` - Polling interval in seconds (default: 60)\n- `--no-sound` - Disable audio notifications\n- `--sound <path>` - Path to a custom sound file\n- `--device <name>` - Audio output device (macOS `afplay -d`)\n- `--priority <level>` - Minimum priority to trigger audio (default: all)\n\nAudio playback uses `afplay` on macOS and tries `play` (sox) then `paplay` on Linux. Audio failures are non-fatal.\n\n### health\n\nCheck server health and version.\n\n```bash\nntfy health\nntfy health --json\nntfy health --all          # check all configured profiles in parallel\n```\n\nExit code 1 if the server is unhealthy.\n\n### delete\n\nDelete a message by its globally-unique message ID.\n\n```bash\nntfy delete abc12345\nntfy delete abc12345 --topic alerts\n```\n\nMessage IDs are shown in `--json` output. The `--topic` flag is accepted for compatibility but not required (IDs are globally unique).\n\n### version\n\n```bash\nntfy version\n```\n\n### topics\n\nManage the list of watched topics for the active profile.\n\n```bash\nntfy topics list                           # show topics and groups\nntfy topics list --json\nntfy topics add work-alerts                # add to watch list\nntfy topics remove old-alerts              # remove from watch list\nntfy topics group add critical alerts ops  # create group \"critical\" with two topics\nntfy topics group remove critical\n```\n\n### completions\n\nGenerate shell completion scripts.\n\n## Shell Completions\n\nShell completions are dynamically populated with your current profile names and topic names.\n\n### Bash\n\n```bash\nntfy completions bash >> ~/.bash_completion\n# or system-wide:\nntfy completions bash > /etc/bash_completion.d/ntfy\n```\n\n### Zsh\n\n```bash\nntfy completions zsh > \"${fpath[1]}/_ntfy\"\n# then reload:\nautoload -U compinit && compinit\n```\n\n### Fish\n\n```bash\nntfy completions fish > ~/.config/fish/completions/ntfy.fish\n```\n\n## Watch Mode\n\nWatch mode is designed for ambient awareness. It polls configured topics on a set interval and plays a sound when new messages arrive.\n\n```bash\n# Watch all topics in the active profile, poll every minute\nntfy watch\n\n# Watch a topic group with faster polling\nntfy watch --group critical --interval 10\n\n# Silence audio but still display messages\nntfy watch --no-sound\n\n# Play a custom sound file\nntfy watch --sound ~/sounds/chime.aiff\n```\n\nWatch mode updates the last-read state just like `ntfy read` does, so `ntfy unread` will correctly exclude messages you saw in a watch session.\n\n## Migrating from Environment Variables\n\nThe original prototype used only environment variables:\n\n```bash\n# Old approach (env-var only)\nexport NTFY_URL=https://ntfy.sh\nexport NTFY_USER=alice\nexport NTFY_PASSWORD=s3cr3t\nexport NTFY_TOPIC=my-alerts\nntfy messages\n```\n\nThis still works as a fallback. But named profiles offer several advantages:\n\n- Multiple servers with one command switch (`--server work`)\n- Multiple topics per profile with unread tracking\n- Named topic groups for batch monitoring\n- Config stored securely at mode 0600\n\n### Migration steps\n\n1. Create a named profile with your existing values:\n\n```bash\nntfy config add home \\\n  --url \"$NTFY_URL\" \\\n  --user \"$NTFY_USER\" \\\n  --password \"$NTFY_PASSWORD\" \\\n  --topic \"$NTFY_TOPIC\"\n```\n\n2. Verify the profile is active:\n\n```bash\nntfy config list\nntfy health\n```\n\n3. Remove the env vars from your shell profile. The named profile takes precedence.\n\n4. Add more topics and profiles as needed:\n\n```bash\nntfy topics add secondary-topic\nntfy config add work --url https://ntfy.work.example.com --user bob --password ... --topic work-alerts\n```\n\n### Precedence order\n\nWhen resolving which profile to use, nitfy follows this order:\n\n1. `--server <name>` flag (explicit override per command)\n2. Active profile from `~/.config/ntfy-cli/config.json`\n3. `NTFY_URL` / `NTFY_USER` / `NTFY_PASSWORD` / `NTFY_TOPIC` environment variables\n\n## Environment Variables\n\n| Variable | Purpose |\n|----------|---------|\n| `NTFY_URL` | Server base URL (fallback when no config) |\n| `NTFY_USER` | Username (fallback) |\n| `NTFY_PASSWORD` | Password (fallback) |\n| `NTFY_TOPIC` | Default topic (fallback) |\n| `NTFY_CONFIG_DIR` | Override config directory (useful for testing) |\n| `NO_COLOR` | Disable ANSI colors when set |\n\nnitfy also reads `NTFY_*` variables from a `.env` file if present in the working directory.\n\n## Exit Codes\n\n| Code | Meaning |\n|------|---------|\n| 0 | Success |\n| 1 | Runtime error (network, auth, server error) |\n| 2 | Usage error (bad arguments, missing required argument) |\n\n## Development\n\n```bash\n# Run tests\nbun test\n\n# Run in dev mode (no build)\nbun run dev -- messages\n\n# Build binary\nbun run build\n```\n\nTests use Bun's built-in test runner with mocked fetch. Integration tests are opt-in:\n\n```bash\nbun test tests/integration/ \\\n  --env NTFY_URL=... NTFY_USER=... NTFY_PASSWORD=... NTFY_TOPIC=...\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-0b33d4e70c9fac8e601259b54abbe062"}