{"_id":"@calebcall/camera-ui-notify","_rev":"16-b2f66e367a62d8a1b26c64eabfb04552","name":"@calebcall/camera-ui-notify","dist-tags":{"latest":"0.9.0"},"versions":{"0.4.0":{"name":"@calebcall/camera-ui-notify","version":"0.4.0","keywords":["camera-ui-plugin","notifier","notifications","ntfy","gotify","webhook","local"],"author":{"url":"https://github.com/calebcall/camera-ui-notify","name":"calebcall"},"license":"MIT","_id":"@calebcall/camera-ui-notify@0.4.0","maintainers":[{"name":"calebcall","email":"calebcall@pm.me"}],"homepage":"https://github.com/calebcall/camera-ui-notify/tree/main#readme","bugs":{"url":"https://github.com/calebcall/camera-ui-notify/issues"},"os":[],"cpu":[],"dist":{"shasum":"d51eb0241531eb0c721030847f713d6fce8e20af","tarball":"https://registry.npmjs.org/@calebcall/camera-ui-notify/-/camera-ui-notify-0.4.0.tgz","fileCount":5,"integrity":"sha512-S3aGplemKeYlJC5IC1sKf7c88vTUU0OO9nh6llVxwa/Tc8iwz5oCKzTdgfQ6kIZ5ljSVDUOl5V5xsGMA1a04sw==","signatures":[{"sig":"MEQCIFgHn1XdZHvhfQawnzFcylYqCjGQJ9dG2koemjv4TlAaAiA/Ky0oNwAyjgARAZdewj5DpJ58/7dSsBQ4mKNyqmDKWQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":699237},"main":"./main.go","type":"commonjs","engines":{"node":">=22.0.0","camera.ui":">=2.0.15"},"gitHead":"6fac97a86e71ce08e5b8d9a0e1a8514b1d66e46e","scripts":{"lint":"staticcheck ./src/... && golangci-lint run ./src/...","test":"go test ./...","build":"rimraf dist && go build -o /dev/null ./src/","bundle":"npm run build && cui bundle","format":"gofmt -w ./src/* && go fix ./src/...","update":"updates --update ./","bundle:dev":"npm run build && cross-env MODE=development cui bundle","publish:beta":"npm i --save --force && npm run bundle && cui publish --beta","publish:alpha":"npm i --save --force && npm run bundle && cui publish --alpha","prepublishOnly":"node -e \"if(!process.env.SAFE_PUBLISH){console.error('Error: Please use @camera.ui/cli to publish the plugin:\\n  npm run publish:alpha\\n  npm run publish:beta\\n  npm run publish:latest\\n');process.exit(1)}\"","publish:latest":"npm i --save --force && npm run bundle && cui publish --latest","install-updates":"npm i --save --force && go mod tidy"},"_npmUser":{"name":"calebcall","email":"calebcall@pm.me"},"repository":{"url":"git+https://github.com/calebcall/camera-ui-notify.git","type":"git"},"_npmVersion":"11.16.0","description":"A fully-local, multi-backend camera.ui notifier plugin: delivers notifications to ntfy, Gotify, or a generic webhook, entirely on your own hardware with no cloud dependency.","directories":{},"displayName":"Notify","_nodeVersion":"24.18.0","_hasShrinkwrap":false,"optionalDependencies":{"@calebcall/camera-ui-notify-linux-amd64":"0.4.0","@calebcall/camera-ui-notify-linux-arm64":"0.4.0","@calebcall/camera-ui-notify-darwin-amd64":"0.4.0","@calebcall/camera-ui-notify-darwin-arm64":"0.4.0","@calebcall/camera-ui-notify-windows-amd64":"0.4.0","@calebcall/camera-ui-notify-windows-arm64":"0.4.0","@calebcall/camera-ui-notify-linux-amd64-musl":"0.4.0","@calebcall/camera-ui-notify-linux-arm64-musl":"0.4.0"},"_npmOperationalInternal":{"tmp":"tmp/camera-ui-notify_0.4.0_1784993684741_0.6809464018483706","host":"s3://npm-registry-packages-npm-production"}},"0.4.1":{"name":"@calebcall/camera-ui-notify","version":"0.4.1","keywords":["camera-ui-plugin","notifier","notifications","ntfy","gotify","webhook","local"],"author":{"url":"https://github.com/calebcall/camera-ui-notify","name":"calebcall"},"license":"MIT","_id":"@calebcall/camera-ui-notify@0.4.1","maintainers":[{"name":"calebcall","email":"calebcall@pm.me"}],"homepage":"https://github.com/calebcall/camera-ui-notify/tree/main#readme","bugs":{"url":"https://github.com/calebcall/camera-ui-notify/issues"},"os":[],"cpu":[],"dist":{"shasum":"d4402f1e8b61e2bcc08dc6beaf037a25069b8ce1","tarball":"https://registry.npmjs.org/@calebcall/camera-ui-notify/-/camera-ui-notify-0.4.1.tgz","fileCount":5,"integrity":"sha512-0OSZKGldXXMBJm2YKSjGMrX+IlhqXGeZEdHnwWIG0HSoTOBuIepwr5SIa0I6Q9uW5P8tLjgbghSIQPbqjp/8ow==","signatures":[{"sig":"MEQCIHU/H2570NEtiHcQ0gtGqkpxE+Lc7Gt6OhZxgs18lFDTAiBXbaPEnGe5efrMG4eWCtg+eoam0i/r0i0MD91YrFdNPQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@calebcall%2fcamera-ui-notify@0.4.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":699034},"main":"./main.go","type":"commonjs","engines":{"node":">=22.0.0","camera.ui":">=2.0.15"},"gitHead":"8d803e4b8babd275ad3596758b0eb07744c8e35a","scripts":{"lint":"staticcheck ./src/... && golangci-lint run ./src/...","test":"go test ./...","build":"rimraf dist && go build -o /dev/null ./src/","bundle":"npm run build && cui bundle","format":"gofmt -w ./src/* && go fix ./src/...","update":"updates --update ./","bundle:dev":"npm run build && cross-env MODE=development cui bundle","publish:beta":"npm i --save --force && npm run bundle && cui publish --beta","publish:alpha":"npm i --save --force && npm run bundle && cui publish --alpha","prepublishOnly":"node -e \"if(!process.env.SAFE_PUBLISH){console.error('Error: Please use @camera.ui/cli to publish the plugin:\\n  npm run publish:alpha\\n  npm run publish:beta\\n  npm run publish:latest\\n');process.exit(1)}\"","publish:latest":"npm i --save --force && npm run bundle && cui publish --latest","install-updates":"npm i --save --force && go mod tidy"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:ec956f07-04aa-4491-9918-6ac4de093c73"}},"repository":{"url":"git+https://github.com/calebcall/camera-ui-notify.git","type":"git"},"_npmVersion":"12.0.1","description":"A fully-local, multi-backend camera.ui notifier plugin: delivers notifications to ntfy, Gotify, or a generic webhook, entirely on your own hardware with no cloud dependency.","directories":{},"displayName":"Notify","_nodeVersion":"22.23.1","_hasShrinkwrap":false,"optionalDependencies":{"@calebcall/camera-ui-notify-linux-amd64":"0.4.1","@calebcall/camera-ui-notify-linux-arm64":"0.4.1","@calebcall/camera-ui-notify-darwin-amd64":"0.4.1","@calebcall/camera-ui-notify-darwin-arm64":"0.4.1","@calebcall/camera-ui-notify-windows-amd64":"0.4.1","@calebcall/camera-ui-notify-windows-arm64":"0.4.1","@calebcall/camera-ui-notify-linux-amd64-musl":"0.4.1","@calebcall/camera-ui-notify-linux-arm64-musl":"0.4.1"},"_npmOperationalInternal":{"tmp":"tmp/camera-ui-notify_0.4.1_1784995668155_0.2286329308001085","host":"s3://npm-registry-packages-npm-production"}},"0.4.2":{"name":"@calebcall/camera-ui-notify","version":"0.4.2","keywords":["camera-ui-plugin","notifier","notifications","ntfy","gotify","webhook","local"],"author":{"url":"https://github.com/calebcall/camera-ui-notify","name":"calebcall"},"license":"MIT","_id":"@calebcall/camera-ui-notify@0.4.2","maintainers":[{"name":"calebcall","email":"calebcall@pm.me"}],"homepage":"https://github.com/calebcall/camera-ui-notify/tree/main#readme","bugs":{"url":"https://github.com/calebcall/camera-ui-notify/issues"},"os":[],"cpu":[],"dist":{"shasum":"aa8f8d18346879cc9832d6ed4f6c3d4891f0f799","tarball":"https://registry.npmjs.org/@calebcall/camera-ui-notify/-/camera-ui-notify-0.4.2.tgz","fileCount":5,"integrity":"sha512-FZVe5OUN18wBGt3Fqgl1WKDxdgfgnEBPtD7wtDcP1vvT2XxmR3JcwliI0kNEA7/1dyZq91p+oFBUMd2xY+GE8A==","signatures":[{"sig":"MEUCIQCcwBalGRcJUFsU/v2Ev/sqDaZOuOD2ROdtAhrkSCmC3QIgJ3/zSy0dIzXGalk3g06VJ9ejTdyeQMPAf45RiTL5PmQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@calebcall%2fcamera-ui-notify@0.4.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":698690},"main":"./main.go","type":"commonjs","engines":{"node":">=22.0.0","camera.ui":">=2.0.15"},"gitHead":"f113ecaadeb5636cf08bc80fe4fa78874ee49b3a","scripts":{"lint":"staticcheck ./src/... && golangci-lint run ./src/...","test":"go test ./...","build":"rimraf dist && go build -o /dev/null ./src/","bundle":"npm run build && cui bundle","format":"gofmt -w ./src/* && go fix ./src/...","update":"updates --update ./","bundle:dev":"npm run build && cross-env MODE=development cui bundle","publish:beta":"npm i --save --force && npm run bundle && cui publish --beta","publish:alpha":"npm i --save --force && npm run bundle && cui publish --alpha","prepublishOnly":"node -e \"if(!process.env.SAFE_PUBLISH){console.error('Error: Please use @camera.ui/cli to publish the plugin:\\n  npm run publish:alpha\\n  npm run publish:beta\\n  npm run publish:latest\\n');process.exit(1)}\"","publish:latest":"npm i --save --force && npm run bundle && cui publish --latest","install-updates":"npm i --save --force && go mod tidy"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:ec956f07-04aa-4491-9918-6ac4de093c73"}},"repository":{"url":"git+https://github.com/calebcall/camera-ui-notify.git","type":"git"},"_npmVersion":"12.0.1","description":"A fully-local, multi-backend camera.ui notifier plugin: delivers notifications to ntfy, Gotify, or a generic webhook, entirely on your own hardware with no cloud dependency.","directories":{},"displayName":"Notify","_nodeVersion":"22.23.1","_hasShrinkwrap":false,"optionalDependencies":{"@calebcall/camera-ui-notify-linux-amd64":"0.4.2","@calebcall/camera-ui-notify-linux-arm64":"0.4.2","@calebcall/camera-ui-notify-darwin-amd64":"0.4.2","@calebcall/camera-ui-notify-darwin-arm64":"0.4.2","@calebcall/camera-ui-notify-windows-amd64":"0.4.2","@calebcall/camera-ui-notify-windows-arm64":"0.4.2","@calebcall/camera-ui-notify-linux-amd64-musl":"0.4.2","@calebcall/camera-ui-notify-linux-arm64-musl":"0.4.2"},"_npmOperationalInternal":{"tmp":"tmp/camera-ui-notify_0.4.2_1785001746520_0.418369464970755","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@calebcall/camera-ui-notify","version":"0.5.0","keywords":["camera-ui-plugin","notifier","notifications","ntfy","gotify","webhook","local"],"author":{"url":"https://github.com/calebcall/camera-ui-notify","name":"calebcall"},"license":"MIT","_id":"@calebcall/camera-ui-notify@0.5.0","maintainers":[{"name":"calebcall","email":"calebcall@pm.me"}],"homepage":"https://github.com/calebcall/camera-ui-notify/tree/main#readme","bugs":{"url":"https://github.com/calebcall/camera-ui-notify/issues"},"os":[],"cpu":[],"dist":{"shasum":"7a1b78ab0626d6d254f35628e92d029d530b64a0","tarball":"https://registry.npmjs.org/@calebcall/camera-ui-notify/-/camera-ui-notify-0.5.0.tgz","fileCount":5,"integrity":"sha512-S2J+ZzDZrpIvE2WUlQjK0HwwPaKijzonLvhbytsDN4E2D154ZnK6efzAqdb7Iry5/aeUwUGBzz7dj8De6X4wTw==","signatures":[{"sig":"MEQCIGjWQxwsyxg19U0Q1TtiBi0+aexowf9Uu41MYZp5LiH8AiAohtISe24CGuwqRB0SO5Nzak67uEFE3RZyoQuLEhpaLg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@calebcall%2fcamera-ui-notify@0.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":699685},"main":"./main.go","type":"commonjs","engines":{"node":">=22.0.0","camera.ui":">=2.0.15"},"gitHead":"06aea8e2944c73d345867ec56d6af6f8adffa64f","scripts":{"lint":"staticcheck ./src/... && golangci-lint run ./src/...","test":"go test ./...","build":"rimraf dist && go build -o /dev/null ./src/","bundle":"npm run build && cui bundle","format":"gofmt -w ./src/* && go fix ./src/...","update":"updates --update ./","bundle:dev":"npm run build && cross-env MODE=development cui bundle","publish:beta":"npm i --save --force && npm run bundle && cui publish --beta","publish:alpha":"npm i --save --force && npm run bundle && cui publish --alpha","prepublishOnly":"node -e \"if(!process.env.SAFE_PUBLISH){console.error('Error: Please use @camera.ui/cli to publish the plugin:\\n  npm run publish:alpha\\n  npm run publish:beta\\n  npm run publish:latest\\n');process.exit(1)}\"","publish:latest":"npm i --save --force && npm run bundle && cui publish --latest","install-updates":"npm i --save --force && go mod tidy"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:ec956f07-04aa-4491-9918-6ac4de093c73"}},"repository":{"url":"git+https://github.com/calebcall/camera-ui-notify.git","type":"git"},"_npmVersion":"12.0.1","description":"A fully-local, multi-backend camera.ui notifier plugin: delivers notifications to ntfy, Gotify, or a generic webhook, entirely on your own hardware with no cloud dependency.","directories":{},"displayName":"Notify","_nodeVersion":"22.23.1","_hasShrinkwrap":false,"optionalDependencies":{"@calebcall/camera-ui-notify-linux-amd64":"0.5.0","@calebcall/camera-ui-notify-linux-arm64":"0.5.0","@calebcall/camera-ui-notify-darwin-amd64":"0.5.0","@calebcall/camera-ui-notify-darwin-arm64":"0.5.0","@calebcall/camera-ui-notify-windows-amd64":"0.5.0","@calebcall/camera-ui-notify-windows-arm64":"0.5.0","@calebcall/camera-ui-notify-linux-amd64-musl":"0.5.0","@calebcall/camera-ui-notify-linux-arm64-musl":"0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/camera-ui-notify_0.5.0_1785022273464_0.9307896973091061","host":"s3://npm-registry-packages-npm-production"}},"0.5.1":{"name":"@calebcall/camera-ui-notify","version":"0.5.1","keywords":["camera-ui-plugin","notifier","notifications","ntfy","gotify","webhook","local"],"author":{"url":"https://github.com/calebcall/camera-ui-notify","name":"calebcall"},"license":"MIT","_id":"@calebcall/camera-ui-notify@0.5.1","maintainers":[{"name":"calebcall","email":"calebcall@pm.me"}],"homepage":"https://github.com/calebcall/camera-ui-notify/tree/main#readme","bugs":{"url":"https://github.com/calebcall/camera-ui-notify/issues"},"os":[],"cpu":[],"dist":{"shasum":"6939655f824eca6d30346add8751c59a68306106","tarball":"https://registry.npmjs.org/@calebcall/camera-ui-notify/-/camera-ui-notify-0.5.1.tgz","fileCount":5,"integrity":"sha512-8LTEZLM9NrrbtUNIwbHquUHivGCrZ6xWsYizUdvXCkDrNo6S6usgaboQ5NcxzA8jcCqkC/YS/voa3JKjmhwoXA==","signatures":[{"sig":"MEQCIFthH3f9g3sYf+dhji2QJKe3nGU9rknUpGgVoNeKyx5EAiAzvF4rKp8Ark0IlxrFVUsFJ0aFr/mtrjj+acJl01MqAQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@calebcall%2fcamera-ui-notify@0.5.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":699901},"main":"./main.go","type":"commonjs","engines":{"node":">=22.0.0","camera.ui":">=2.0.15"},"gitHead":"b50ab99dd9fc529f90c1642f339af5eeff9dbace","scripts":{"lint":"staticcheck ./src/... && golangci-lint run ./src/...","test":"go test ./...","build":"rimraf dist && go build -o /dev/null ./src/","bundle":"npm run build && cui bundle","format":"gofmt -w ./src/* && go fix ./src/...","update":"updates --update ./","bundle:dev":"npm run build && cross-env MODE=development cui bundle","publish:beta":"npm i --save --force && npm run bundle && cui publish --beta","publish:alpha":"npm i --save --force && npm run bundle && cui publish --alpha","prepublishOnly":"node -e \"if(!process.env.SAFE_PUBLISH){console.error('Error: Please use @camera.ui/cli to publish the plugin:\\n  npm run publish:alpha\\n  npm run publish:beta\\n  npm run publish:latest\\n');process.exit(1)}\"","publish:latest":"npm i --save --force && npm run bundle && cui publish --latest","install-updates":"npm i --save --force && go mod tidy"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:ec956f07-04aa-4491-9918-6ac4de093c73"}},"repository":{"url":"git+https://github.com/calebcall/camera-ui-notify.git","type":"git"},"_npmVersion":"12.0.1","description":"A fully-local, multi-backend camera.ui notifier plugin: delivers notifications to ntfy, Gotify, or a generic webhook, entirely on your own hardware with no cloud dependency.","directories":{},"displayName":"Notify","_nodeVersion":"22.23.1","_hasShrinkwrap":false,"optionalDependencies":{"@calebcall/camera-ui-notify-linux-amd64":"0.5.1","@calebcall/camera-ui-notify-linux-arm64":"0.5.1","@calebcall/camera-ui-notify-darwin-amd64":"0.5.1","@calebcall/camera-ui-notify-darwin-arm64":"0.5.1","@calebcall/camera-ui-notify-windows-amd64":"0.5.1","@calebcall/camera-ui-notify-windows-arm64":"0.5.1","@calebcall/camera-ui-notify-linux-amd64-musl":"0.5.1","@calebcall/camera-ui-notify-linux-arm64-musl":"0.5.1"},"_npmOperationalInternal":{"tmp":"tmp/camera-ui-notify_0.5.1_1785022447106_0.23032403849765926","host":"s3://npm-registry-packages-npm-production"}},"0.5.2":{"name":"@calebcall/camera-ui-notify","version":"0.5.2","keywords":["camera-ui-plugin","notifier","notifications","ntfy","gotify","webhook","local"],"author":{"url":"https://github.com/calebcall/camera-ui-notify","name":"calebcall"},"license":"MIT","_id":"@calebcall/camera-ui-notify@0.5.2","maintainers":[{"name":"calebcall","email":"calebcall@pm.me"}],"homepage":"https://github.com/calebcall/camera-ui-notify/tree/main#readme","bugs":{"url":"https://github.com/calebcall/camera-ui-notify/issues"},"os":[],"cpu":[],"dist":{"shasum":"b6d379b5f0debac73a63016bfc780ec1697e587b","tarball":"https://registry.npmjs.org/@calebcall/camera-ui-notify/-/camera-ui-notify-0.5.2.tgz","fileCount":5,"integrity":"sha512-KkfpBN5/5DlFO3nqvc4U88VhkTb+wV7ch7UcY2AQ7PQ+ydQPL9qYnJcA2pnF0UWXclueHWZYLalgfO/NwuI/Yw==","signatures":[{"sig":"MEUCIQDbr1peBIwFVHUslSoY76OB11JMR8UGOUdzPtrC4PS3BwIgNkrsH7hdRu5k8OyECKTzowKqEENFeklZCEDbN1dkWjw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@calebcall%2fcamera-ui-notify@0.5.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":700678},"main":"./main.go","type":"commonjs","engines":{"node":">=22.0.0","camera.ui":">=2.0.15"},"gitHead":"8aa70bd05a7caba292afa576841554cceb5dff78","scripts":{"lint":"staticcheck ./src/... && golangci-lint run ./src/...","test":"go test ./...","build":"rimraf dist && go build -o /dev/null ./src/","bundle":"npm run build && cui bundle","format":"gofmt -w ./src/* && go fix ./src/...","update":"updates --update ./","bundle:dev":"npm run build && cross-env MODE=development cui bundle","publish:beta":"npm i --save --force && npm run bundle && cui publish --beta","publish:alpha":"npm i --save --force && npm run bundle && cui publish --alpha","prepublishOnly":"node -e \"if(!process.env.SAFE_PUBLISH){console.error('Error: Please use @camera.ui/cli to publish the plugin:\\n  npm run publish:alpha\\n  npm run publish:beta\\n  npm run publish:latest\\n');process.exit(1)}\"","publish:latest":"npm i --save --force && npm run bundle && cui publish --latest","install-updates":"npm i --save --force && go mod tidy"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:ec956f07-04aa-4491-9918-6ac4de093c73"}},"repository":{"url":"git+https://github.com/calebcall/camera-ui-notify.git","type":"git"},"_npmVersion":"12.0.1","description":"A fully-local, multi-backend camera.ui notifier plugin: delivers notifications to ntfy, Gotify, or a generic webhook, entirely on your own hardware with no cloud dependency.","directories":{},"displayName":"Notify","_nodeVersion":"22.23.1","_hasShrinkwrap":false,"optionalDependencies":{"@calebcall/camera-ui-notify-linux-amd64":"0.5.2","@calebcall/camera-ui-notify-linux-arm64":"0.5.2","@calebcall/camera-ui-notify-darwin-amd64":"0.5.2","@calebcall/camera-ui-notify-darwin-arm64":"0.5.2","@calebcall/camera-ui-notify-windows-amd64":"0.5.2","@calebcall/camera-ui-notify-windows-arm64":"0.5.2","@calebcall/camera-ui-notify-linux-amd64-musl":"0.5.2","@calebcall/camera-ui-notify-linux-arm64-musl":"0.5.2"},"_npmOperationalInternal":{"tmp":"tmp/camera-ui-notify_0.5.2_1785118034400_0.8390021485376022","host":"s3://npm-registry-packages-npm-production"}},"0.5.3":{"name":"@calebcall/camera-ui-notify","version":"0.5.3","keywords":["camera-ui-plugin","notifier","notifications","ntfy","gotify","webhook","local"],"author":{"url":"https://github.com/calebcall/camera-ui-notify","name":"calebcall"},"license":"MIT","_id":"@calebcall/camera-ui-notify@0.5.3","maintainers":[{"name":"calebcall","email":"calebcall@pm.me"}],"homepage":"https://github.com/calebcall/camera-ui-notify/tree/main#readme","bugs":{"url":"https://github.com/calebcall/camera-ui-notify/issues"},"os":[],"cpu":[],"dist":{"shasum":"2378b8cede4a4a465bc276b276f1fc880e579d98","tarball":"https://registry.npmjs.org/@calebcall/camera-ui-notify/-/camera-ui-notify-0.5.3.tgz","fileCount":5,"integrity":"sha512-OkJWHMTMmLhGSGA+yHf6eaWFQ1P9eD2qnERlewPJ2aWpXKF8/eCk7kwj6ozf7pYh97Qwdxv2+L8jdPls/inekQ==","signatures":[{"sig":"MEYCIQCyPaLpOeis1r1qrEYVwKDbhgrPxc/N/+Nx5NgnYOhJNwIhAPaRi0qu4Sag/q8NQWR4PthkCiduzgAxNiiwnl7lZeP+","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@calebcall%2fcamera-ui-notify@0.5.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":701376},"main":"./main.go","type":"commonjs","engines":{"node":">=22.0.0","camera.ui":">=2.0.15"},"gitHead":"25d4f3de1d577eb2df416ae83232c75b911d4e5e","scripts":{"lint":"staticcheck ./src/... && golangci-lint run ./src/...","test":"go test ./...","build":"rimraf dist && go build -o /dev/null ./src/","bundle":"npm run build && cui bundle","format":"gofmt -w ./src/* && go fix ./src/...","update":"updates --update ./","bundle:dev":"npm run build && cross-env MODE=development cui bundle","publish:beta":"npm i --save --force && npm run bundle && cui publish --beta","publish:alpha":"npm i --save --force && npm run bundle && cui publish --alpha","prepublishOnly":"node -e \"if(!process.env.SAFE_PUBLISH){console.error('Error: Please use @camera.ui/cli to publish the plugin:\\n  npm run publish:alpha\\n  npm run publish:beta\\n  npm run publish:latest\\n');process.exit(1)}\"","publish:latest":"npm i --save --force && npm run bundle && cui publish --latest","install-updates":"npm i --save --force && go mod tidy"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:ec956f07-04aa-4491-9918-6ac4de093c73"}},"repository":{"url":"git+https://github.com/calebcall/camera-ui-notify.git","type":"git"},"_npmVersion":"12.0.2","description":"A fully-local, multi-backend camera.ui notifier plugin: delivers notifications to ntfy, Gotify, or a generic webhook, entirely on your own hardware with no cloud dependency.","directories":{},"displayName":"Notify","_nodeVersion":"22.23.1","_hasShrinkwrap":false,"optionalDependencies":{"@calebcall/camera-ui-notify-linux-amd64":"0.5.3","@calebcall/camera-ui-notify-linux-arm64":"0.5.3","@calebcall/camera-ui-notify-darwin-amd64":"0.5.3","@calebcall/camera-ui-notify-darwin-arm64":"0.5.3","@calebcall/camera-ui-notify-windows-amd64":"0.5.3","@calebcall/camera-ui-notify-windows-arm64":"0.5.3","@calebcall/camera-ui-notify-linux-amd64-musl":"0.5.3","@calebcall/camera-ui-notify-linux-arm64-musl":"0.5.3"},"_npmOperationalInternal":{"tmp":"tmp/camera-ui-notify_0.5.3_1785372201104_0.2993130514519291","host":"s3://npm-registry-packages-npm-production"}},"0.5.4":{"name":"@calebcall/camera-ui-notify","version":"0.5.4","keywords":["camera-ui-plugin","notifier","notifications","ntfy","gotify","webhook","local"],"author":{"url":"https://github.com/calebcall/camera-ui-notify","name":"calebcall"},"license":"MIT","_id":"@calebcall/camera-ui-notify@0.5.4","maintainers":[{"name":"calebcall","email":"calebcall@pm.me"}],"homepage":"https://github.com/calebcall/camera-ui-notify/tree/main#readme","bugs":{"url":"https://github.com/calebcall/camera-ui-notify/issues"},"os":[],"cpu":[],"dist":{"shasum":"b935d1dd8895efb2be6da8d0276c63b54aecc832","tarball":"https://registry.npmjs.org/@calebcall/camera-ui-notify/-/camera-ui-notify-0.5.4.tgz","fileCount":5,"integrity":"sha512-vhj45VcNScsnEGq/N+RMvl6SWQJQ1NPOAQxppGxvgzgJCUjQdEIcvFlMMAwL95Lef5gxfyWmZ4tYfBww8OkJdQ==","signatures":[{"sig":"MEUCIQD0RLmyUWT6peHA/qoQRY44PltBo7oNrKz1YaARdiGyXAIgeFseBecdtg+6zMhTgut+xxTNg4iOo5dATyyijGaAMsU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@calebcall%2fcamera-ui-notify@0.5.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":704998},"main":"./main.go","type":"commonjs","engines":{"node":">=22.0.0","camera.ui":">=2.0.23"},"gitHead":"900abc46536f94323ffde9f1684c0836646911c9","scripts":{"lint":"staticcheck ./src/... && golangci-lint run ./src/...","test":"go test ./...","build":"rimraf dist && go build -o /dev/null ./src/","bundle":"npm run build && cui bundle","format":"gofmt -w ./src/* && go fix ./src/...","update":"updates --update ./","bundle:dev":"npm run build && cross-env MODE=development cui bundle","publish:beta":"npm i --save --force && npm run bundle && cui publish --beta","publish:alpha":"npm i --save --force && npm run bundle && cui publish --alpha","prepublishOnly":"node -e \"if(!process.env.SAFE_PUBLISH){console.error('Error: Please use @camera.ui/cli to publish the plugin:\\n  npm run publish:alpha\\n  npm run publish:beta\\n  npm run publish:latest\\n');process.exit(1)}\"","publish:latest":"npm i --save --force && npm run bundle && cui publish --latest","install-updates":"npm i --save --force && go mod tidy"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:ec956f07-04aa-4491-9918-6ac4de093c73"}},"cameraui":{"protocolLevel":1},"repository":{"url":"git+https://github.com/calebcall/camera-ui-notify.git","type":"git"},"_npmVersion":"12.0.2","description":"A fully-local, multi-backend camera.ui notifier plugin: delivers notifications to ntfy, Gotify, or a generic webhook, entirely on your own hardware with no cloud dependency.","directories":{},"displayName":"Notify","_nodeVersion":"22.23.1","_hasShrinkwrap":false,"optionalDependencies":{"@calebcall/camera-ui-notify-linux-amd64":"0.5.4","@calebcall/camera-ui-notify-linux-arm64":"0.5.4","@calebcall/camera-ui-notify-darwin-amd64":"0.5.4","@calebcall/camera-ui-notify-darwin-arm64":"0.5.4","@calebcall/camera-ui-notify-windows-amd64":"0.5.4","@calebcall/camera-ui-notify-windows-arm64":"0.5.4","@calebcall/camera-ui-notify-linux-amd64-musl":"0.5.4","@calebcall/camera-ui-notify-linux-arm64-musl":"0.5.4"},"_npmOperationalInternal":{"tmp":"tmp/camera-ui-notify_0.5.4_1785530382858_0.8113208764143083","host":"s3://npm-registry-packages-npm-production"}},"0.5.5":{"name":"@calebcall/camera-ui-notify","version":"0.5.5","keywords":["camera-ui-plugin","notifier","notifications","ntfy","gotify","webhook","local"],"author":{"url":"https://github.com/calebcall/camera-ui-notify","name":"calebcall"},"license":"MIT","_id":"@calebcall/camera-ui-notify@0.5.5","maintainers":[{"name":"calebcall","email":"calebcall@pm.me"}],"homepage":"https://github.com/calebcall/camera-ui-notify/tree/main#readme","bugs":{"url":"https://github.com/calebcall/camera-ui-notify/issues"},"os":[],"cpu":[],"dist":{"shasum":"87865546196b15319ae4e5273838e5b952a98b91","tarball":"https://registry.npmjs.org/@calebcall/camera-ui-notify/-/camera-ui-notify-0.5.5.tgz","fileCount":5,"integrity":"sha512-UjBa4GyIylh3P+ZBULQ/lx4h8FlSZ6izDr55gbDaUSXhoQw1v7W/iNgeWX1WU3f0myiurG/LO6oIZTu//1Yviw==","signatures":[{"sig":"MEUCIQDM32n3N4OKhXRLAw/gAklf+rSwnyZVVbXTuXUtAVzPhwIgLrUcpiEWZ0PaVpGXd8TsKv+lrgcFlcJ+KX0Cxm/NCLw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@calebcall%2fcamera-ui-notify@0.5.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":707244},"main":"./main.go","type":"commonjs","engines":{"node":">=22.0.0","camera.ui":">=2.0.24"},"gitHead":"ad1d8322417bb383eb87d1ee6b40b5aa336b97d4","scripts":{"lint":"staticcheck ./src/... && golangci-lint run ./src/...","test":"go test ./...","build":"rimraf dist && go build -o /dev/null ./src/","bundle":"npm run build && cui bundle","format":"gofmt -w ./src/* && go fix ./src/...","update":"updates --update ./","bundle:dev":"npm run build && cross-env MODE=development cui bundle","publish:beta":"npm i --save --force && npm run bundle && cui publish --beta","publish:alpha":"npm i --save --force && npm run bundle && cui publish --alpha","prepublishOnly":"node -e \"if(!process.env.SAFE_PUBLISH){console.error('Error: Please use @camera.ui/cli to publish the plugin:\\n  npm run publish:alpha\\n  npm run publish:beta\\n  npm run publish:latest\\n');process.exit(1)}\"","publish:latest":"npm i --save --force && npm run bundle && cui publish --latest","install-updates":"npm i --save --force && go mod tidy"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:ec956f07-04aa-4491-9918-6ac4de093c73"}},"cameraui":{"protocolLevel":1},"repository":{"url":"git+https://github.com/calebcall/camera-ui-notify.git","type":"git"},"_npmVersion":"12.0.2","description":"A fully-local, multi-backend camera.ui notifier plugin: delivers notifications to ntfy, Gotify, or a generic webhook, entirely on your own hardware with no cloud dependency.","directories":{},"displayName":"Notify","_nodeVersion":"22.23.1","_hasShrinkwrap":false,"optionalDependencies":{"@calebcall/camera-ui-notify-linux-amd64":"0.5.5","@calebcall/camera-ui-notify-linux-arm64":"0.5.5","@calebcall/camera-ui-notify-darwin-amd64":"0.5.5","@calebcall/camera-ui-notify-darwin-arm64":"0.5.5","@calebcall/camera-ui-notify-windows-amd64":"0.5.5","@calebcall/camera-ui-notify-windows-arm64":"0.5.5","@calebcall/camera-ui-notify-linux-amd64-musl":"0.5.5","@calebcall/camera-ui-notify-linux-arm64-musl":"0.5.5"},"_npmOperationalInternal":{"tmp":"tmp/camera-ui-notify_0.5.5_1785557477623_0.05586044058143602","host":"s3://npm-registry-packages-npm-production"}},"0.5.6":{"name":"@calebcall/camera-ui-notify","version":"0.5.6","keywords":["camera-ui-plugin","notifier","notifications","ntfy","gotify","webhook","local"],"author":{"url":"https://github.com/calebcall/camera-ui-notify","name":"calebcall"},"license":"MIT","_id":"@calebcall/camera-ui-notify@0.5.6","maintainers":[{"name":"calebcall","email":"calebcall@pm.me"}],"homepage":"https://github.com/calebcall/camera-ui-notify/tree/main#readme","bugs":{"url":"https://github.com/calebcall/camera-ui-notify/issues"},"os":[],"cpu":[],"dist":{"shasum":"1dc6f40162fdc6edd3d457ad784e058ae9b0689c","tarball":"https://registry.npmjs.org/@calebcall/camera-ui-notify/-/camera-ui-notify-0.5.6.tgz","fileCount":5,"integrity":"sha512-U5WmFrBWQ/IHewT1VcsYQuImF/+ET0OuexGB6xMpBT0LZYiNpYb0V8uwLhMoI/46Ij8SmIjTwqdauxkbT9R/Lw==","signatures":[{"sig":"MEUCIQDz4Vy3mUqMmOcj88dOoQJe5OWkM0rDIXSoJ2iPec5qxAIgEsOv8F26AqEKL7TLBEBJM8+Uu3WdL+M4YtxrkmZib78=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@calebcall%2fcamera-ui-notify@0.5.6","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":708850},"main":"./main.go","type":"commonjs","engines":{"node":">=22.0.0","camera.ui":">=2.0.24"},"gitHead":"2b5166758e45388314a41418a95829e19e6aa090","scripts":{"lint":"staticcheck ./src/... && golangci-lint run ./src/...","test":"go test ./...","build":"rimraf dist && go build -o /dev/null ./src/","bundle":"npm run build && cui bundle","format":"gofmt -w ./src/* && go fix ./src/...","update":"updates --update ./","bundle:dev":"npm run build && cross-env MODE=development cui bundle","publish:beta":"npm i --save --force && npm run bundle && cui publish --beta","publish:alpha":"npm i --save --force && npm run bundle && cui publish --alpha","prepublishOnly":"node -e \"if(!process.env.SAFE_PUBLISH){console.error('Error: Please use @camera.ui/cli to publish the plugin:\\n  npm run publish:alpha\\n  npm run publish:beta\\n  npm run publish:latest\\n');process.exit(1)}\"","publish:latest":"npm i --save --force && npm run bundle && cui publish --latest","install-updates":"npm i --save --force && go mod tidy"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:ec956f07-04aa-4491-9918-6ac4de093c73"}},"cameraui":{"protocolLevel":1},"repository":{"url":"git+https://github.com/calebcall/camera-ui-notify.git","type":"git"},"_npmVersion":"12.0.2","description":"A fully-local, multi-backend camera.ui notifier plugin: delivers notifications to ntfy, Gotify, or a generic webhook, entirely on your own hardware with no cloud dependency.","directories":{},"displayName":"Notify","_nodeVersion":"22.23.1","_hasShrinkwrap":false,"optionalDependencies":{"@calebcall/camera-ui-notify-linux-amd64":"0.5.6","@calebcall/camera-ui-notify-linux-arm64":"0.5.6","@calebcall/camera-ui-notify-darwin-amd64":"0.5.6","@calebcall/camera-ui-notify-darwin-arm64":"0.5.6","@calebcall/camera-ui-notify-windows-amd64":"0.5.6","@calebcall/camera-ui-notify-windows-arm64":"0.5.6","@calebcall/camera-ui-notify-linux-amd64-musl":"0.5.6","@calebcall/camera-ui-notify-linux-arm64-musl":"0.5.6"},"_npmOperationalInternal":{"tmp":"tmp/camera-ui-notify_0.5.6_1785589778417_0.22427592778895789","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@calebcall/camera-ui-notify","version":"0.6.0","keywords":["camera-ui-plugin","notifier","notifications","ntfy","gotify","webhook","local"],"author":{"url":"https://github.com/calebcall/camera-ui-notify","name":"calebcall"},"license":"MIT","_id":"@calebcall/camera-ui-notify@0.6.0","maintainers":[{"name":"calebcall","email":"calebcall@pm.me"}],"homepage":"https://github.com/calebcall/camera-ui-notify/tree/main#readme","bugs":{"url":"https://github.com/calebcall/camera-ui-notify/issues"},"os":[],"cpu":[],"dist":{"shasum":"0f0825ccd324c03741347f50ccb8cbb658dc8f9b","tarball":"https://registry.npmjs.org/@calebcall/camera-ui-notify/-/camera-ui-notify-0.6.0.tgz","fileCount":5,"integrity":"sha512-pq9h9MCV1wNjBX3iyHANIj038VOYpSygZS8v3fDM8Td1Eb0xBoNdJrX3w4Uiwz7B9aPGf+tPz3juxXWu8zj4RA==","signatures":[{"sig":"MEYCIQCYYssFqor0hfypfskOgon1r/EC9AGzI38GM0JYsIhSsgIhAO4uqRn5Cg+2C6ZIqzFeWRV0THLrRtkLWxafTjHM6v3Z","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@calebcall%2fcamera-ui-notify@0.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":713131},"main":"./main.go","type":"commonjs","engines":{"node":">=22.0.0","camera.ui":">=2.0.24"},"gitHead":"4d35eb7c27d579991e3ac63425a4ee6e8a1739b7","scripts":{"lint":"staticcheck ./src/... && golangci-lint run ./src/...","test":"go test ./...","build":"rimraf dist && go build -o /dev/null ./src/","bundle":"npm run build && cui bundle","format":"gofmt -w ./src/* && go fix ./src/...","update":"updates --update ./","bundle:dev":"npm run build && cross-env MODE=development cui bundle","publish:beta":"npm i --save --force && npm run bundle && cui publish --beta","publish:alpha":"npm i --save --force && npm run bundle && cui publish --alpha","prepublishOnly":"node -e \"if(!process.env.SAFE_PUBLISH){console.error('Error: Please use @camera.ui/cli to publish the plugin:\\n  npm run publish:alpha\\n  npm run publish:beta\\n  npm run publish:latest\\n');process.exit(1)}\"","publish:latest":"npm i --save --force && npm run bundle && cui publish --latest","install-updates":"npm i --save --force && go mod tidy"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:ec956f07-04aa-4491-9918-6ac4de093c73"}},"cameraui":{"protocolLevel":1},"repository":{"url":"git+https://github.com/calebcall/camera-ui-notify.git","type":"git"},"_npmVersion":"12.0.2","description":"A fully-local, multi-backend camera.ui notifier plugin: delivers notifications to ntfy, Gotify, or a generic webhook, entirely on your own hardware with no cloud dependency.","directories":{},"displayName":"Notify","_nodeVersion":"22.23.1","_hasShrinkwrap":false,"optionalDependencies":{"@calebcall/camera-ui-notify-linux-amd64":"0.6.0","@calebcall/camera-ui-notify-linux-arm64":"0.6.0","@calebcall/camera-ui-notify-darwin-amd64":"0.6.0","@calebcall/camera-ui-notify-darwin-arm64":"0.6.0","@calebcall/camera-ui-notify-windows-amd64":"0.6.0","@calebcall/camera-ui-notify-windows-arm64":"0.6.0","@calebcall/camera-ui-notify-linux-amd64-musl":"0.6.0","@calebcall/camera-ui-notify-linux-arm64-musl":"0.6.0"},"_npmOperationalInternal":{"tmp":"tmp/camera-ui-notify_0.6.0_1785639929481_0.8667619436822063","host":"s3://npm-registry-packages-npm-production"}},"0.6.1":{"name":"@calebcall/camera-ui-notify","version":"0.6.1","keywords":["camera-ui-plugin","notifier","notifications","ntfy","gotify","webhook","local"],"author":{"url":"https://github.com/calebcall/camera-ui-notify","name":"calebcall"},"license":"MIT","_id":"@calebcall/camera-ui-notify@0.6.1","maintainers":[{"name":"calebcall","email":"calebcall@pm.me"}],"homepage":"https://github.com/calebcall/camera-ui-notify/tree/main#readme","bugs":{"url":"https://github.com/calebcall/camera-ui-notify/issues"},"os":[],"cpu":[],"dist":{"shasum":"c38294c2ba0d29b3c319de25312a9aa5c7a6c500","tarball":"https://registry.npmjs.org/@calebcall/camera-ui-notify/-/camera-ui-notify-0.6.1.tgz","fileCount":5,"integrity":"sha512-CbcA66dNS2bNb+QBR+/2pWL65wTy87Gb7SwA1ezjgwJGKUs5Vvj1HlO1ak/1iw/W7byWssu4KO5D/jyA/66zsA==","signatures":[{"sig":"MEUCIQDsECuJm4niRq41eYT/KjhejrjPsiSbFC+aQAj1j8OqjQIgdgJPiVM9azQnLAumQpiD4kYsFBBEjDMGhsII2rW0wOo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@calebcall%2fcamera-ui-notify@0.6.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":716444},"main":"./main.go","type":"commonjs","engines":{"node":">=22.0.0","camera.ui":">=2.0.24"},"gitHead":"e3e8f8a46c5d5012d1ffca16779ff65a06f32eab","scripts":{"lint":"staticcheck ./src/... && golangci-lint run ./src/...","test":"go test ./...","build":"rimraf dist && go build -o /dev/null ./src/","bundle":"npm run build && cui bundle","format":"gofmt -w ./src/* && go fix ./src/...","update":"updates --update ./","bundle:dev":"npm run build && cross-env MODE=development cui bundle","publish:beta":"npm i --save --force && npm run bundle && cui publish --beta","publish:alpha":"npm i --save --force && npm run bundle && cui publish --alpha","prepublishOnly":"node -e \"if(!process.env.SAFE_PUBLISH){console.error('Error: Please use @camera.ui/cli to publish the plugin:\\n  npm run publish:alpha\\n  npm run publish:beta\\n  npm run publish:latest\\n');process.exit(1)}\"","publish:latest":"npm i --save --force && npm run bundle && cui publish --latest","install-updates":"npm i --save --force && go mod tidy"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:ec956f07-04aa-4491-9918-6ac4de093c73"}},"cameraui":{"protocolLevel":1},"repository":{"url":"git+https://github.com/calebcall/camera-ui-notify.git","type":"git"},"_npmVersion":"12.0.2","description":"A fully-local, multi-backend camera.ui notifier plugin: delivers notifications to ntfy, Gotify, or a generic webhook, entirely on your own hardware with no cloud dependency.","directories":{},"displayName":"Notify","_nodeVersion":"22.23.1","_hasShrinkwrap":false,"optionalDependencies":{"@calebcall/camera-ui-notify-linux-amd64":"0.6.1","@calebcall/camera-ui-notify-linux-arm64":"0.6.1","@calebcall/camera-ui-notify-darwin-amd64":"0.6.1","@calebcall/camera-ui-notify-darwin-arm64":"0.6.1","@calebcall/camera-ui-notify-windows-amd64":"0.6.1","@calebcall/camera-ui-notify-windows-arm64":"0.6.1","@calebcall/camera-ui-notify-linux-amd64-musl":"0.6.1","@calebcall/camera-ui-notify-linux-arm64-musl":"0.6.1"},"_npmOperationalInternal":{"tmp":"tmp/camera-ui-notify_0.6.1_1785644237995_0.40653408654767587","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@calebcall/camera-ui-notify","version":"0.7.0","keywords":["camera-ui-plugin","notifier","notifications","ntfy","gotify","webhook","local"],"author":{"url":"https://github.com/calebcall/camera-ui-notify","name":"calebcall"},"license":"MIT","_id":"@calebcall/camera-ui-notify@0.7.0","maintainers":[{"name":"calebcall","email":"calebcall@pm.me"}],"homepage":"https://github.com/calebcall/camera-ui-notify/tree/main#readme","bugs":{"url":"https://github.com/calebcall/camera-ui-notify/issues"},"os":[],"cpu":[],"dist":{"shasum":"2354b10f32c2c83d3111c23a233d5eee2eeb10fc","tarball":"https://registry.npmjs.org/@calebcall/camera-ui-notify/-/camera-ui-notify-0.7.0.tgz","fileCount":5,"integrity":"sha512-VXVzqt29CZswG6Nro0U5cvDKhmQhz4Vlc6w3G0oHFG9hiWjc8PnVN8mrZTVORYiu1s8ZNPP1JDb6ZnljZdYoxA==","signatures":[{"sig":"MEQCIDqvXla6nDL3ZBP5hX8n1T7UDDW+3Qy98FIimFogKZi+AiA1IcuHX/H30HvKG9hwAfhR+FJJZKMgW5vwqEagUygMdw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@calebcall%2fcamera-ui-notify@0.7.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":722965},"main":"./main.go","type":"commonjs","engines":{"node":">=22.0.0","camera.ui":">=2.0.24"},"gitHead":"43b1ffe37be042a35ef33ad16b758a9e62379e52","scripts":{"lint":"staticcheck ./src/... && golangci-lint run ./src/...","test":"go test ./...","build":"rimraf dist && go build -o /dev/null ./src/","bundle":"npm run build && cui bundle","format":"gofmt -w ./src/* && go fix ./src/...","update":"updates --update ./","bundle:dev":"npm run build && cross-env MODE=development cui bundle","publish:beta":"npm i --save --force && npm run bundle && cui publish --beta","publish:alpha":"npm i --save --force && npm run bundle && cui publish --alpha","prepublishOnly":"node -e \"if(!process.env.SAFE_PUBLISH){console.error('Error: Please use @camera.ui/cli to publish the plugin:\\n  npm run publish:alpha\\n  npm run publish:beta\\n  npm run publish:latest\\n');process.exit(1)}\"","publish:latest":"npm i --save --force && npm run bundle && cui publish --latest","install-updates":"npm i --save --force && go mod tidy"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:ec956f07-04aa-4491-9918-6ac4de093c73"}},"cameraui":{"protocolLevel":1},"repository":{"url":"git+https://github.com/calebcall/camera-ui-notify.git","type":"git"},"_npmVersion":"12.0.2","description":"A fully-local, multi-backend camera.ui notifier plugin: delivers notifications to ntfy, Gotify, or a generic webhook, entirely on your own hardware with no cloud dependency.","directories":{},"displayName":"Notify","_nodeVersion":"22.23.1","_hasShrinkwrap":false,"optionalDependencies":{"@calebcall/camera-ui-notify-linux-amd64":"0.7.0","@calebcall/camera-ui-notify-linux-arm64":"0.7.0","@calebcall/camera-ui-notify-darwin-amd64":"0.7.0","@calebcall/camera-ui-notify-darwin-arm64":"0.7.0","@calebcall/camera-ui-notify-windows-amd64":"0.7.0","@calebcall/camera-ui-notify-windows-arm64":"0.7.0","@calebcall/camera-ui-notify-linux-amd64-musl":"0.7.0","@calebcall/camera-ui-notify-linux-arm64-musl":"0.7.0"},"_npmOperationalInternal":{"tmp":"tmp/camera-ui-notify_0.7.0_1785646505987_0.7704060694610848","host":"s3://npm-registry-packages-npm-production"}},"0.7.1":{"name":"@calebcall/camera-ui-notify","version":"0.7.1","keywords":["camera-ui-plugin","notifier","notifications","ntfy","gotify","webhook","local"],"author":{"url":"https://github.com/calebcall/camera-ui-notify","name":"calebcall"},"license":"MIT","_id":"@calebcall/camera-ui-notify@0.7.1","maintainers":[{"name":"calebcall","email":"calebcall@pm.me"}],"homepage":"https://github.com/calebcall/camera-ui-notify/tree/main#readme","bugs":{"url":"https://github.com/calebcall/camera-ui-notify/issues"},"os":[],"cpu":[],"dist":{"shasum":"45340ae46117ac96e26733a955bfbc09311f57bd","tarball":"https://registry.npmjs.org/@calebcall/camera-ui-notify/-/camera-ui-notify-0.7.1.tgz","fileCount":5,"integrity":"sha512-VQL1pZikbRVKv9IK2rsTkvUOzSipUSYC51cSfPi1yZy1gZW+Rq/g8KmEPPVoGDh1G53cZInrL4sY0PocRv23xw==","signatures":[{"sig":"MEUCIQDINu1lNFfcywR+5A0AvhcyLjCoGVIAQutw0ay2Pe1rRwIgDfsRlL3tfSvO50KZCSxKBTrbrzSwzbPiEEmST0ezVRY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@calebcall%2fcamera-ui-notify@0.7.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":728195},"main":"./main.go","type":"commonjs","engines":{"node":">=22.0.0","camera.ui":">=2.0.24"},"gitHead":"5430c1da9f4d0f47873d775cbe4e8bfb46190bb1","scripts":{"lint":"staticcheck ./src/... && golangci-lint run ./src/...","test":"go test ./...","build":"rimraf dist && go build -o /dev/null ./src/","bundle":"npm run build && cui bundle","format":"gofmt -w ./src/* && go fix ./src/...","update":"updates --update ./","bundle:dev":"npm run build && cross-env MODE=development cui bundle","publish:beta":"npm i --save --force && npm run bundle && cui publish --beta","publish:alpha":"npm i --save --force && npm run bundle && cui publish --alpha","prepublishOnly":"node -e \"if(!process.env.SAFE_PUBLISH){console.error('Error: Please use @camera.ui/cli to publish the plugin:\\n  npm run publish:alpha\\n  npm run publish:beta\\n  npm run publish:latest\\n');process.exit(1)}\"","publish:latest":"npm i --save --force && npm run bundle && cui publish --latest","install-updates":"npm i --save --force && go mod tidy"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:ec956f07-04aa-4491-9918-6ac4de093c73"}},"cameraui":{"protocolLevel":1},"repository":{"url":"git+https://github.com/calebcall/camera-ui-notify.git","type":"git"},"_npmVersion":"12.0.2","description":"A fully-local, multi-backend camera.ui notifier plugin: delivers notifications to ntfy, Gotify, or a generic webhook, entirely on your own hardware with no cloud dependency.","directories":{},"displayName":"Notify","_nodeVersion":"22.23.1","_hasShrinkwrap":false,"optionalDependencies":{"@calebcall/camera-ui-notify-linux-amd64":"0.7.1","@calebcall/camera-ui-notify-linux-arm64":"0.7.1","@calebcall/camera-ui-notify-darwin-amd64":"0.7.1","@calebcall/camera-ui-notify-darwin-arm64":"0.7.1","@calebcall/camera-ui-notify-windows-amd64":"0.7.1","@calebcall/camera-ui-notify-windows-arm64":"0.7.1","@calebcall/camera-ui-notify-linux-amd64-musl":"0.7.1","@calebcall/camera-ui-notify-linux-arm64-musl":"0.7.1"},"_npmOperationalInternal":{"tmp":"tmp/camera-ui-notify_0.7.1_1785649509064_0.8288021727152097","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"@calebcall/camera-ui-notify","version":"0.8.0","keywords":["camera-ui-plugin","notifier","notifications","ntfy","gotify","webhook","local"],"author":{"url":"https://github.com/calebcall/camera-ui-notify","name":"calebcall"},"license":"MIT","_id":"@calebcall/camera-ui-notify@0.8.0","maintainers":[{"name":"calebcall","email":"calebcall@pm.me"}],"homepage":"https://github.com/calebcall/camera-ui-notify/tree/main#readme","bugs":{"url":"https://github.com/calebcall/camera-ui-notify/issues"},"os":[],"cpu":[],"dist":{"shasum":"5cf231ef7202b649c2e94332e0cff4ab22400c27","tarball":"https://registry.npmjs.org/@calebcall/camera-ui-notify/-/camera-ui-notify-0.8.0.tgz","fileCount":5,"integrity":"sha512-Z99E6W6sseUp7CvHzdGgMWOCTHtVH5MyXwhrFajBeCJgyEnhCsngkZ0Y3FXeh00uP1h22mq+auQyaZY5aw7jjA==","signatures":[{"sig":"MEUCIGm4/CecUUUDHkSd5h78rtwtTwAJf436F57AczMyJtt6AiEA0Qbov0ApvehZYjjWiPRb3zz9FdMAe40QVaehVqq6Xd4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@calebcall%2fcamera-ui-notify@0.8.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":735197},"main":"./main.go","type":"commonjs","engines":{"node":">=22.0.0","camera.ui":">=2.0.24"},"gitHead":"91068fb4b1d4ee133fff12255ba4c1d197e4d34e","scripts":{"lint":"golangci-lint run ./src/...","test":"go test ./...","build":"rimraf dist && go build -o /dev/null ./src/","bundle":"npm run build && cui bundle","format":"gofmt -w ./src/* && go fix ./src/...","update":"updates --update ./","bundle:dev":"npm run build && cross-env MODE=development cui bundle","publish:beta":"npm i --save --force && npm run bundle && cui publish --beta","publish:alpha":"npm i --save --force && npm run bundle && cui publish --alpha","prepublishOnly":"node -e \"if(!process.env.SAFE_PUBLISH){console.error('Error: Please use @camera.ui/cli to publish the plugin:\\n  npm run publish:alpha\\n  npm run publish:beta\\n  npm run publish:latest\\n');process.exit(1)}\"","publish:latest":"npm i --save --force && npm run bundle && cui publish --latest","install-updates":"npm i --save --force && go mod tidy"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:ec956f07-04aa-4491-9918-6ac4de093c73"}},"cameraui":{"protocolLevel":1},"repository":{"url":"git+https://github.com/calebcall/camera-ui-notify.git","type":"git"},"_npmVersion":"12.0.2","description":"A fully-local, multi-backend camera.ui notifier plugin: delivers notifications to ntfy, Gotify, Pushover, Telegram, Discord, Grafana, or a generic webhook, entirely on your own hardware with no cloud dependency.","directories":{},"displayName":"Notify","_nodeVersion":"22.23.1","_hasShrinkwrap":false,"optionalDependencies":{"@calebcall/camera-ui-notify-linux-amd64":"0.8.0","@calebcall/camera-ui-notify-linux-arm64":"0.8.0","@calebcall/camera-ui-notify-darwin-amd64":"0.8.0","@calebcall/camera-ui-notify-darwin-arm64":"0.8.0","@calebcall/camera-ui-notify-windows-amd64":"0.8.0","@calebcall/camera-ui-notify-windows-arm64":"0.8.0","@calebcall/camera-ui-notify-linux-amd64-musl":"0.8.0","@calebcall/camera-ui-notify-linux-arm64-musl":"0.8.0"},"_npmOperationalInternal":{"tmp":"tmp/camera-ui-notify_0.8.0_1786483300307_0.06125193936629714","host":"s3://npm-registry-packages-npm-production"}},"0.9.0":{"displayName":"Notify","name":"@calebcall/camera-ui-notify","version":"0.9.0","description":"A fully-local, multi-backend camera.ui notifier plugin: delivers notifications to ntfy, Gotify, Pushover, Telegram, Discord, Grafana, or a generic webhook, entirely on your own hardware with no cloud dependency.","author":{"name":"calebcall","url":"https://github.com/calebcall/camera-ui-notify"},"main":"./main.go","type":"commonjs","scripts":{"build":"rimraf dist && go build -o /dev/null ./src/","bundle":"npm run build && cui bundle","bundle:dev":"npm run build && cross-env MODE=development cui bundle","format":"gofmt -w ./src/* && go fix ./src/...","install-updates":"npm i --save --force && go mod tidy","lint":"golangci-lint run ./src/...","prepublishOnly":"node -e \"if(!process.env.SAFE_PUBLISH){console.error('Error: Please use @camera.ui/cli to publish the plugin:\\n  npm run publish:alpha\\n  npm run publish:beta\\n  npm run publish:latest\\n');process.exit(1)}\"","publish:alpha":"npm i --save --force && npm run bundle && cui publish --alpha","publish:beta":"npm i --save --force && npm run bundle && cui publish --beta","publish:latest":"npm i --save --force && npm run bundle && cui publish --latest","test":"go test ./...","update":"updates --update ./"},"license":"MIT","bugs":{"url":"https://github.com/calebcall/camera-ui-notify/issues"},"engines":{"camera.ui":">=2.1.6","node":">=22.0.0"},"homepage":"https://github.com/calebcall/camera-ui-notify/tree/main#readme","keywords":["camera-ui-plugin","notifier","notifications","ntfy","gotify","webhook","local"],"repository":{"type":"git","url":"git+https://github.com/calebcall/camera-ui-notify.git"},"os":[],"cpu":[],"cameraui":{"protocolLevel":1},"optionalDependencies":{"@calebcall/camera-ui-notify-darwin-arm64":"0.9.0","@calebcall/camera-ui-notify-darwin-amd64":"0.9.0","@calebcall/camera-ui-notify-linux-amd64":"0.9.0","@calebcall/camera-ui-notify-linux-arm64":"0.9.0","@calebcall/camera-ui-notify-windows-amd64":"0.9.0","@calebcall/camera-ui-notify-windows-arm64":"0.9.0","@calebcall/camera-ui-notify-linux-amd64-musl":"0.9.0","@calebcall/camera-ui-notify-linux-arm64-musl":"0.9.0"},"gitHead":"2e27678705ef5666db33cb91917f9fe6f2f65d9d","_id":"@calebcall/camera-ui-notify@0.9.0","_nodeVersion":"22.23.1","_npmVersion":"12.0.2","dist":{"integrity":"sha512-pSxXu23wSma0bykOK3q+Zkil+77L92ceL/ThhEvfVxroMmWrdQ2TCJS6bxckXIqptUIFt4o4OkCLBXQHcAZRUQ==","shasum":"60d96bba25883b58ee6815322e28b6ceb96a807e","tarball":"https://registry.npmjs.org/@calebcall/camera-ui-notify/-/camera-ui-notify-0.9.0.tgz","fileCount":5,"unpackedSize":745055,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@calebcall%2fcamera-ui-notify@0.9.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCo3A+iGv5fk4elHAmy7zVl8q1JLQvcnlZtHF4BYtdnQgIhAKkv56QsUzC2G5lGinY38H3RdPvKlINZw9P2CN1/tzSP"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:ec956f07-04aa-4491-9918-6ac4de093c73"}},"directories":{},"maintainers":[{"name":"calebcall","email":"calebcall@pm.me"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/camera-ui-notify_0.9.0_1786573263422_0.9075083013447534"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-25T15:34:44.551Z","modified":"2026-08-12T22:21:04.036Z","0.4.0":"2026-07-25T15:34:44.997Z","0.4.1":"2026-07-25T16:07:48.354Z","0.4.2":"2026-07-25T17:49:06.719Z","0.5.0":"2026-07-25T23:31:13.716Z","0.5.1":"2026-07-25T23:34:07.313Z","0.5.2":"2026-07-27T02:07:14.596Z","0.5.3":"2026-07-30T00:43:21.272Z","0.5.4":"2026-07-31T20:39:43.031Z","0.5.5":"2026-08-01T04:11:17.841Z","0.5.6":"2026-08-01T13:09:38.634Z","0.6.0":"2026-08-02T03:05:29.684Z","0.6.1":"2026-08-02T04:17:18.162Z","0.7.0":"2026-08-02T04:55:06.156Z","0.7.1":"2026-08-02T05:45:09.267Z","0.8.0":"2026-08-11T21:21:40.640Z","0.9.0":"2026-08-12T22:21:03.610Z"},"bugs":{"url":"https://github.com/calebcall/camera-ui-notify/issues"},"author":{"name":"calebcall","url":"https://github.com/calebcall/camera-ui-notify"},"license":"MIT","homepage":"https://github.com/calebcall/camera-ui-notify/tree/main#readme","keywords":["camera-ui-plugin","notifier","notifications","ntfy","gotify","webhook","local"],"repository":{"type":"git","url":"git+https://github.com/calebcall/camera-ui-notify.git"},"description":"A fully-local, multi-backend camera.ui notifier plugin: delivers notifications to ntfy, Gotify, Pushover, Telegram, Discord, Grafana, or a generic webhook, entirely on your own hardware with no cloud dependency.","maintainers":[{"name":"calebcall","email":"calebcall@pm.me"}],"readme":"<h1 align=\"center\">Notify</h1>\n\n<p align=\"center\">\n  A fully-local, multi-backend <a href=\"https://github.com/seydx/camera.ui\">camera.ui</a> notifier\n  plugin — delivers notifications to a service you control (<a href=\"https://ntfy.sh\">ntfy</a>,\n  <a href=\"https://gotify.net\">Gotify</a>, Pushover, Telegram, Discord,\n  <a href=\"https://grafana.com\">Grafana</a>, or a generic webhook).\n</p>\n\n---\n\n## Why this exists\n\n\nThere is intentionally no notifier in the open ecosystem: the closed, official NVR bundles a notifier that pushed to the camera.ui mobile app through camera.ui's proprietary FCM/APNs cloud relay. This plugin takes the only fully-local road to real background push instead: delivering to a push/webhook service *you* run or control.\n\nThis plugin is a pure **notifier**. It is decoupled from any single publisher — it delivers notifications from **any** publisher, including our NVR plugin's detection events and camera.ui's own system notifications, not just one plugin's output.\n\n## How it works\n\nOne plugin, contract `interfaces: [Notifier]`, built around a pluggable-backend (strategy) pattern:\n\n- A `Backend` interface abstracts one delivery service (id, label, config schema, target validation, and delivery).\n- A package-level registry maps each backend's stable id to its implementation; every backend self-registers from its own `init()`.\n- The plugin holds **one active target** in its own persisted config (`StorageSchema`): which service is selected, plus that service's validated fields. `getDevices` synthesizes a single `sdk.NotifierDevice` from this config on every call — there is no device registry.\n- `sendNotification` dispatches the synthesized device to its backend's `Send`. A backend failure is logged and returned to the host.\n\n### Why config, not device registration\n\nEarlier versions of this plugin modeled targets as registrable `NotifierDevice`s, the way camera.ui's own mobile-push notifier does. That model turned out to be unreachable from the stock UI: `registerDevice` is only ever called by the camera.ui mobile app's push-registration flow, which is hardcoded to the official NVR's plugin name. The generic notification settings panel renders `notificationSettings()` read-only — it has no \"add a device\" affordance for third-party plugins. The one part of the stock UI that **does** render an editable, savable form for a third-party plugin is its own settings page, which renders whatever `StorageSchema` the plugin declares. So Notify now models its target as plugin config instead of a device: you configure it once, in the plugin's own settings, and `getDevices` synthesizes the device the host's `Notifier` interface expects from that config.\n\nAdding a new backend later is **one new file** — `src/backend/<name>.go` implementing `Backend` plus `Register(...)` in its `init()` — and a version bump. No new plugin, no core change, no changes to `plugin.go`.\n\n## Backends (v1)\n\nSeverity is mapped consistently across backends via `backend.PriorityScale`, which spreads camera.ui's four severity levels (`info` → `warn` → `error` → `critical`) evenly across each backend's native priority range, `info` at the low end and `critical` at the high end. Grafana is the exception: no Grafana surface has a numeric priority, so severity travels verbatim as a label/tag.\n\n### ntfy\n\nPublishes to [ntfy.sh](https://ntfy.sh) or a self-hosted ntfy server.\n\n| Field    | Required | Default              | Notes                                              |\n| -------- | -------- | --------------------- | --------------------------------------------------- |\n| `server` | no       | `https://ntfy.sh`     | Base URL of the ntfy server. Trailing `/` trimmed. |\n| `topic`  | yes      | —                     | The ntfy topic to publish to.                      |\n| `token`  | no       | —                     | Access token for a protected/self-hosted topic, sent as `Authorization: Bearer <token>`. |\n\nDelivery: `POST {server}/{topic}` with the notification body as the request body, plus `Title`, `Priority` (1–5, from severity), `Click` (deep link, if set), `Attach`/`Icon` (image URL, if set), and `Actions` (a \"Play clip\" view button, if a video clip is set) headers.\n\n### Gotify\n\nPublishes to a self-hosted [Gotify](https://gotify.net) server.\n\n| Field    | Required | Notes                                          |\n| -------- | -------- | ----------------------------------------------- |\n| `server` | yes      | Base URL of the Gotify server. Trailing `/` trimmed. |\n| `token`  | yes      | Gotify application token, used to authenticate published messages. |\n\nDelivery: `POST {server}/message?token={token}` with a JSON body `{title, message, priority}` (priority 0–10, from severity), plus a `client::notification.click` extra for the deep link and a `bigImageUrl` extra when an image URL is set. A video clip is appended to the message text as a `Play clip: <url>` line.\n\n### Generic webhook\n\nDelivers to any HTTP endpoint you provide — the fallback for anything without a dedicated backend.\n\n| Field         | Required | Default | Notes                                                         |\n| ------------- | -------- | ------- | -------------------------------------------------------------- |\n| `url`         | yes      | —       | Endpoint that receives the notification.                       |\n| `method`      | no       | `POST`  | `POST` or `PUT`.                                                |\n| `headerName`  | no       | —       | Optional custom header name (e.g. for a shared secret). Requires `headerValue` if set. |\n| `headerValue` | no       | —       | Value of the custom header. Requires `headerName` if set.       |\n\nDelivery: `{method} {url}` with `Content-Type: application/json` and (if configured) the custom header, carrying a JSON body of `{title, subtitle, body, severity, tag, silent, imageUrl, videoUrl, deepLink, data, createdAt, thumbnailBase64}`.\n\n### Pushover\n\nHosted push to the [Pushover](https://pushover.net) app.\n\n| Field    | Required | Notes                                          |\n| -------- | -------- | ---------------------------------------------- |\n| `token`  | yes      | Pushover application API token/key.            |\n| `user`   | yes      | Your Pushover user or group key.               |\n\nDelivery: `POST https://api.pushover.net/1/messages.json` with title/message and a priority (Info→0 normal, everything higher→1 high; never emergency). The snapshot **image** is sent as an `attachment`, and an absolute deep link becomes a supplementary `url` titled \"Open camera\" for a detection or \"Open in camera.ui\" for anything else. A video clip takes that `url` slot when no deep link claims it, and otherwise appends a `Play clip: <url>` line to the message.\n\n### Telegram\n\nDelivers to a chat via a [Telegram bot](https://core.telegram.org/bots).\n\n| Field   | Required | Notes                                                    |\n| ------- | -------- | -------------------------------------------------------- |\n| `token` | yes      | Bot token from @BotFather.                               |\n| `chat`  | yes      | Chat ID to deliver to.                                   |\n| `clip`  | no       | **Upload video clips** — off by default. See [Video clips](#video-clips-video-in-push). |\n\nDelivery: `sendPhoto` (with the snapshot **image** + caption) when a thumbnail is present, otherwise `sendMessage` — or `sendVideo` when clip upload is on and the notification carries a clip. An absolute deep link is added as an inline button, labelled \"Open camera\" when it opens a camera page and \"Open in camera.ui\" otherwise; a video clip adds a second \"Play clip\" button below it, unless it is being uploaded.\n\n### Discord\n\nDelivers to a channel via a Discord [webhook](https://support.discord.com/hc/en-us/articles/228383668).\n\n| Field     | Required | Notes                                   |\n| --------- | -------- | --------------------------------------- |\n| `webhook` | yes      | Channel webhook URL.                    |\n| `clip`    | no       | **Upload video clips** — off by default. See [Video clips](#video-clips-video-in-push). |\n\nDelivery: a rich embed (title, body, severity color — blue/yellow/red) with the snapshot **image** attached; an absolute deep link makes the title a link, and a video clip is appended to the description as a `Play clip` link — or uploaded as a second attachment when clip upload is on.\n\n### Grafana\n\nDelivers to the [Grafana](https://grafana.com) ecosystem. This is not one ingest endpoint, so a\n**Mode** field selects which surface receives the notification — and the three modes address three\ndifferent services, so each has its own connection fields.\n\n| Field                   | Required | Mode          | Notes                                                    |\n| ----------------------- | -------- | ------------- | --------------------------------------------------------- |\n| `grafana_mode`          | yes      | —             | `annotations`, `alertmanager`, or `irm`. Defaults to `annotations`. |\n| `grafana_server`        | yes      | annotations   | Base URL of the Grafana instance. Trailing `/` trimmed.   |\n| `grafana_token`         | yes      | annotations   | Service-account token, sent as `Authorization: Bearer <token>`. |\n| `grafana_tags`          | no       | annotations   | Comma-separated extra tags.                               |\n| `grafana_am_url`        | yes      | alertmanager  | Base URL of the **Alertmanager**, not of Grafana — **including any path prefix** (see below). A pasted `.../api/v2/alerts` endpoint is accepted and trimmed. |\n| `grafana_am_user`       | no       | alertmanager  | Basic-auth username. For Grafana Cloud, the numeric Alertmanager instance ID. |\n| `grafana_am_password`   | no       | alertmanager  | Basic-auth password. For Grafana Cloud, an Access Policy token with the `alerts:write` scope. Required if a username is set, and vice versa. |\n| `grafana_alertname`     | no       | alertmanager  | `alertname` label. Defaults to `CameraUINotification`.    |\n| `grafana_ttl`           | no       | alertmanager  | Seconds before Alertmanager auto-resolves the alert. Default `900`, minimum `30`. |\n| `grafana_irm_url`       | yes      | irm           | Inbound webhook URL of an IRM / OnCall integration. The token is in the URL, so it is masked and kept out of every error message. |\n\n**Annotations** — `POST {server}/api/annotations` with a point-in-time, organization-wide\nannotation tagged `camera.ui`, `camera:<name>`, `severity:<level>`, plus your extra tags. Surface it\non a dashboard with an annotation query filtered on the `camera.ui` tag; that survives dashboard\nrenames, which pinning to a dashboard UID would not. The tooltip text carries the title, the body,\nand — when `base_url` is set — a link back to camera.ui.\n\n**Alertmanager** — `POST {alertmanager}/api/v2/alerts`, straight to an Alertmanager's own API, with\noptional basic auth. Works with a standalone Prometheus Alertmanager, Mimir/Cortex, or Grafana\nCloud's hosted Alertmanager (username = instance ID, password = API token).\n\n> **This mode does not talk to Grafana**, and it deliberately cannot. Grafana's built-in\n> Alertmanager will not accept posted alerts: its route table exposes `GET` for alerts but declares\n> the `POST` route only as `/alertmanager/{DatasourceUID}/api/v2/alerts`, a proxy to an *external*\n> Alertmanager, with no `grafana` variant. Grafana-managed alerts can only come from Grafana's own\n> rule evaluation. Point this at a real Alertmanager. (Versions 0.6.0–0.6.1 targeted Grafana here\n> and always failed with `400 bad request data`.)\n\n> **Get the URL right — this is the most common way to misconfigure this mode.** Mimir and Grafana\n> Cloud serve the Alertmanager API under a path prefix, `/alertmanager` by default; a standalone\n> Alertmanager serves it at the root. Omit the prefix and every send fails with a bare\n> `404 page not found`.\n>\n> | Target | Enter | Resulting POST |\n> | --- | --- | --- |\n> | Grafana Cloud / Mimir | `https://alertmanager-prod-xx.grafana.net/alertmanager` | `…/alertmanager/api/v2/alerts` |\n> | Standalone Alertmanager | `http://alertmanager:9093` | `…/api/v2/alerts` |\n>\n> **Grafana Cloud credentials** come from two different places. The **username** is the numeric\n> Alertmanager instance ID, shown with the URL on the Alertmanager details page in the Cloud\n> portal. The **password** is an **Access Policy token** (`glc_…`) carrying the `alerts:write`\n> scope, created under Access Policies — *not* a Grafana service-account token (`glsa_…`), which\n> authenticates to Grafana rather than to the Alertmanager.\n\n`endsAt` is `now + grafana_ttl`, which lets Alertmanager auto-resolve the alert without a\nsecond request. `startsAt` is deliberately not sent — Alertmanager stamps it from its own clock.\n\n> **If sends succeed but no alert appears, check the clock.** `endsAt` has to be absolute\n> (Alertmanager's API has no relative form), so it is computed from the camera.ui host's clock. A\n> host running more than `grafana_ttl` *behind* the Alertmanager sends an `endsAt` already in the\n> past: the alert is accepted with a `200`, resolved on arrival, and never shows as active. The\n> symptom is a clean `notify: delivered` in the log and an empty\n> `GET {alertmanager}/api/v2/alerts`. Keep the host in NTP sync. The 900-second default exists to\n> give that failure some margin.\n>\n> Second, gentler trap: alerts self-resolve after `grafana_ttl` and drop off the active list, so\n> when testing, look within the window rather than an hour later. Labels are `alertname`, `source=camera.ui`, `severity` (camera.ui's own four\nlevels, verbatim), `camera`, `camera_id`, and a unique `event_id` — the last of these matters, because\nAlertmanager deduplicates on the label set and without it two detections on one camera inside the\nTTL window would collapse into a single alert. The absolute deep link becomes `generatorURL`,\nwhich Alertmanager shows as **Source**.\n\n**IRM** — `POST {integration URL}`. IRM renders each alert group through templates chosen by the\nintegration's *type*, and the two types people actually create read different bodies, so the\npayload carries both: Grafana Alerting's webhook envelope (`status`, `alerts[]` with\nlabels/annotations/`generatorURL`/`imageURL`, `groupKey`, `commonLabels`, `externalURL`) for a\n**Grafana Alerting** integration, and OnCall's formatted-webhook fields (`alert_uid`, `image_url`,\n`link_to_upstream_details`) for a **Webhook** integration. `title`, `message`, and\n`state=alerting` are read by both. One body, correct under either type, nothing to configure.\n\nAlert groups are keyed **per camera** — `camera.ui:<camera>`, falling back to `camera.ui` for a\nnotification that names no camera — so one busy camera can't bury a quiet one. Within a group each\nevent keeps its own `fingerprint`, so detections stay individually visible.\n\n**IRM groups do not auto-resolve.** IRM decides that from a template on the payload's status — its\ndefault is `{{ payload.status == \"resolved\" }}` — so a group closes only when a *second* request\narrives saying so. `endsAt` is ignored, which is why alerts carry the documented never-resolves\nsentinel rather than a future time that would imply a close that never comes. This plugin sends one\nstateless POST per event and no follow-up, by design: a delayed resolve would mean a background\ntimer and per-event state, and a restart would strand the group open anyway. Close them in IRM.\n\n> **Camera names:** `camera` carries the camera's display name, taken from `Data[\"cameraName\"]`\n> when a publisher supplies one and otherwise from the deep link, which camera.ui routes by name.\n> `Data[\"cameraId\"]` is a UUID for the publishers seen so far, so it is kept separately as\n> `camera_id` (alertmanager and IRM modes) for routing rules that must survive a rename. With\n> neither a name nor a deep link, `camera` falls back to the id.\n\n> **Images:** ntfy, Pushover, Telegram, and Discord all render the detection snapshot. Gotify is\n> text + link only (it needs a hosted image URL, which this fully-local plugin doesn't provide).\n> Grafana renders one only in IRM mode, and only when the publisher supplied a hosted `ImageURL` —\n> annotations have no image field at all, and alerts carry the URL as an `image_url` annotation\n> that Grafana itself won't render but downstream notification templates can use.\n\n> **Video clips:** annotations mode adds a `Play clip` anchor to the annotation tooltip; the\n> alertmanager and IRM modes carry the URL as a `video_url` annotation, alongside `image_url` and\n> on the same terms — Grafana won't render it, downstream templates can use it.\n\n> **Secrets in logs:** transport failures never log the bot token / webhook URL / other\n> URL-embedded secret — request URLs are redacted from delivery errors.\n\n## Follow-up updates (AI descriptions)\n\ncamera.ui announces a detection immediately, then republishes the same notification a few seconds later once the AI description is ready. Both publishes carry the same `tag` (the collapse key), and the second carries `silent: true`, meaning *this only updates the first one — don't alert again*.\n\nHandled per backend, according to what each platform can actually do:\n\n| Backend         | Follow-up behaviour                                                                  |\n| --------------- | ------------------------------------------------------------------------------------ |\n| Telegram        | **Replaces** the original message (`editMessageText` / `editMessageCaption`).         |\n| Discord         | **Replaces** the original message (`PATCH .../messages/{id}`).                        |\n| Grafana         | **Revises** the record it already filed — see below.                                  |\n| ntfy            | Delivered at priority `1` — visible, no sound or vibration.                           |\n| Gotify          | Delivered at priority `3` — joins the in-app list, raises no system notification.      |\n| Pushover        | Delivered at priority `-1` (quiet) — no sound or vibration.                            |\n| Generic webhook | `silent: true` is forwarded in the JSON payload; your endpoint decides.               |\n\nGrafana revises per mode: **annotations** patches the annotation it created (`PATCH /api/annotations/:id`), so the dashboard keeps one marker at the detection's own timestamp whose text improves. **Alertmanager** and **IRM** re-file under the `event_id` / `alert_uid` the first alert used — that identity is what each surface deduplicates on, so the existing alert or group picks up the description instead of a second one firing. When the publisher supplies its own `Data[\"eventId\"]`, that id is authoritative and the two publishes already share it, so those modes update correctly even across a plugin restart.\n\nThe replacing backends therefore show **one** notification whose text improves in place. The message id is remembered in memory per tag for 15 minutes; after a plugin restart, or if the original message was deleted, the update is delivered as a new (quiet) message instead of being lost.\n\nOnly the `silent` follow-up replaces. Detection tags repeat across events (`motion:cam-1` is the same tag every time that camera sees something), so a *new* alert reusing a tag always posts a new message — your chat history is never rewritten by a later event.\n\n**Critical alerts ignore `silent`** — a `critical` severity notification always alerts, per the SDK contract.\n\nIf you would rather never see the follow-up on a backend that can't replace, set **Follow-up updates** to `Skip the update entirely` in the plugin settings. Backends that replace in place still receive it under that setting, since editing adds nothing to the notification list — with the one caveat that a lost message id (restart, deleted message) turns that edit into a new quiet message.\n\n## Video clips (\"Video in Push\")\n\ncamera.ui 2.1.6 added `videoUrl` to the notification payload: a short MP4 of the recording that\ntriggered the alert, published when the camera — or, for a multi-camera episode, the episode —\nhas **Video in Push** switched on under its notification settings. Whether a clip is published at\nall is decided there, per camera, not here — this plugin only forwards what it is handed.\n\n### By default: the clip is a link\n\nNothing this plugin talks to is the first-party mobile app, so no backend plays the clip *inside*\nthe push the way an iOS attachment does. What each one can do is offer the clip as a link, opened\nin the phone's own browser or player — already authenticated to your server. The rule is the same\neverywhere: **the clip is added, never substituted.** The snapshot keeps its attachment slot and\nthe deep link keeps its click target, because the deep link opens the event in camera.ui, from\nwhich the recording is one tap away, whereas the clip on its own is a dead end.\n\n| Backend         | How the clip is surfaced                                                          |\n| --------------- | ----------------------------------------------------------------------------------- |\n| ntfy            | A `Play clip` **view action button** (the single `Attach` slot stays with the snapshot). |\n| Telegram        | A second **inline button** below the deep-link button.                              |\n| Discord         | A `Play clip` link at the end of the embed description.                             |\n| Pushover        | The supplementary `url` when no deep link claims it; otherwise a line in the message. |\n| Gotify          | A `Play clip: <url>` line appended to the message text.                             |\n| Grafana         | An anchor in the annotation tooltip; a `video_url` annotation in alertmanager/IRM modes. |\n| Generic webhook | A `videoUrl` field in the JSON payload, forwarded verbatim.                         |\n\n**A linked clip has to be reachable from the phone.** camera.ui publishes the URL absolute; a\nserver-relative one is made absolute with the **camera.ui Base URL** setting, the same way deep\nlinks are. Without that setting a relative clip URL is dropped rather than delivered as a link\nthat cannot open — except on the generic webhook, whose receiver is a machine that may well be\nable to resolve it, so there it is forwarded as-is.\n\n### Opt in: upload the clip (Telegram, Discord)\n\nTelegram and Discord can carry the video itself, and both render a real player in the chat. Turn\non **Upload video clips** in the plugin settings for either one and the plugin downloads the clip\nfrom camera.ui and re-uploads the bytes to the service. Nothing outside your network ever fetches\nfrom your server — the plugin is the only client that touches the clip URL — so this works for an\ninstall that isn't reachable from the internet at all.\n\n| | Telegram | Discord |\n| --- | --- | --- |\n| Method | `sendVideo`, `supports_streaming` on so it plays while downloading | a `clip.mp4` file attachment beside the embed |\n| Snapshot | **replaced** — Telegram carries one media item per message | **kept**, still rendered inside the embed |\n| Size cap | 50 MB (the Bot API's own upload limit) | 8 MB (Discord allows 10 MB per request on an unboosted server; the headroom is for the snapshot) |\n| Follow-up cost | none — `editMessageCaption` leaves the video in place, so the AI description doesn't re-download it | one more download + upload — Discord's edit drops any attachment the request doesn't re-send |\n\nIt is off by default because it is the expensive path: the default merely passes a URL along,\nwhile this moves the whole file twice for every detection. The Discord row above is the one to\nweigh — a busy camera with clip upload on moves each clip **four** times once the AI description\nlands.\n\n**Every failure falls back to the link, never to a lost notification.** A clip past the size cap\nis not downloaded at all (a `Content-Length` over the limit fails before the body is read); a\ndownload that errors or stalls, and an upload the service rejects, both retry immediately as an\nordinary send with the `Play clip` link. Oversize clips are rejected rather than truncated — a\nclipped MP4 is a broken upload, not a smaller video. Each fallback is logged with its reason.\n\n## Configuring your target (v1: one active target)\n\nThere is no \"add device\" flow. Instead, configure the plugin itself:\n\n1. Open the **Notify** plugin's page in camera.ui (Plugins → Notify).\n2. In its settings, pick a **Service** (`ntfy`, `Gotify`, `Generic webhook`, `Pushover`, `Telegram`, `Discord`, or `Grafana`) from the dropdown built from the registered backends.\n3. Fill in that service's fields — only the selected service's fields are shown; the rest are condition-gated out.\n4. Optionally set **Follow-up updates** (see [Follow-up updates](#follow-up-updates-ai-descriptions)) — defaults to delivering the AI description quietly.\n5. On Telegram or Discord, optionally turn on **Upload video clips** (see [Video clips](#video-clips-video-in-push)) — off by default.\n6. Save. The config is validated (`ParseTarget`) the next time a notification is dispatched; `getDevices` then synthesizes one delivery target from it, and notifications from any publisher are delivered there.\n\nThis is a **single, instance-wide target** in v1 — there's no way to register several devices at once. Changing the config replaces the previous target rather than adding to it. Delivery for that one target is a single request per notification (no fan-out to worry about, since there's only one device).\n\n## Tech stack\n\n- **Go** (matches the NVR plugin; same build/deploy toolchain).\n- **camera.ui SDK (Go)** for the plugin runtime, the `Notifier` RPC surface, and device storage.\n- Delivery via each backend's plain HTTP API using the Go stdlib `net/http` — no third-party HTTP client libraries.\n- Config persistence via the plugin's own `DeviceStorage`, holding the selected service and its fields as declared by `StorageSchema()` — no SQLite; it's a handful of scalar values.\n\n## Prerequisites\n\n- **Go 1.26+** (to build the plugin binary).\n- **Node.js 22+** and the plugin's dev dependencies (`npm install`) to produce the `contract.cjs` bundle via the camera.ui CLI.\n- A running camera.ui instance you control (the host where the plugin gets installed).\n\n## Build & deploy locally\n\ncamera.ui loads the **built artifact**, not source — a `git pull` alone does nothing. You must build the bundle (`contract.cjs` + the platform binary) and copy it into the install slot.\n\nThe install slot is:\n\n```\n<camera.ui-install>/plugins/@calebcall/camera-ui-notify/\n```\n\nand the plugin's config (the selected service and its fields) lives under `<camera.ui-install>/volume/plugins/storage/@calebcall/camera-ui-notify/` — reinstalling the code does not touch it.\n\n> **Unlike the NVR plugin**, there is no hardcoded-package-id requirement here: the camera.ui host\n> discovers notifiers by the `Notifier` **interface** declared in the plugin's contract, not by a\n> fixed package name. This plugin can be installed under its own real name/namespace.\n\n### Option A — build natively on the server (preferred)\n\nIf Go 1.26+ and Node are available on the host, build there and skip the cross-compile round-trip:\n\n```bash\n# 1. Get the latest source\ncd ~/path/to/plugins && git pull\ncd camera-ui-notify\nnpm install                 # first time only — pulls the camera.ui CLI bundler\n\n# 2. Build the bundle (produces bundle/{contract.cjs, package.json, dist/bin/plugin})\nnpm run bundle:dev\n\n# 3. Install into the @calebcall/camera-ui-notify slot\nD=<camera.ui-install>/plugins/@calebcall/camera-ui-notify\nmkdir -p \"$D\" && rm -rf \"$D\"/* && cp -a bundle/. \"$D/\"\n\n# 4. Restart camera.ui\nsystemctl restart cameraui   # or however your instance is managed\n```\n\n### Option B — cross-compile from a workstation\n\nBuild a statically-linked Linux binary locally, then ship the bundle to the server:\n\n```bash\ncd camera-ui-notify\n\n# 1. Produce contract.cjs (+ package.json) under bundle/\nnpm install\nnpm run bundle:dev\n\n# 2. Cross-compile the Linux binary into the bundle's dev path\nGOOS=linux GOARCH=amd64 CGO_ENABLED=0 \\ go build -ldflags \"-s -w\" -o bundle/dist/bin/plugin ./src/\nchmod 755 bundle/dist/bin/plugin\n\n# 3. Ship it (strip macOS junk so the server dir stays clean)\nCOPYFILE_DISABLE=1 tar czf /tmp/notify-install.tgz -C bundle .\nscp /tmp/notify-install.tgz root@YOUR_SERVER:/tmp/\n\n# 4. On the server: install into the slot, enable (first time), restart\nssh root@YOUR_SERVER 'D=<camera.ui-install>/plugins/@calebcall/camera-ui-notify mkdir -p \"$D\" && rm -rf \"$D\"/* && tar xzf /tmp/notify-install.tgz -C \"$D\"; systemctl restart cameraui'\n```\n\nSet `GOARCH=arm64` for ARM hosts. The binary is resolved from the dev path `<slot>/dist/bin/plugin` before any platform `node_modules` package, so no npm publish is involved.\n\n### Verify it loaded and is being used\n\nTail the camera.ui log after restart:\n\n```bash\ngrep -iE \"Notify|Spawning Go|notify: rpc\" <camera.ui-install>/volume/camera.ui.log | tail\n```\n\nYou want to see the plugin spawn (`Spawning Go plugin ... dist/bin/plugin`) **and** the host actually calling into it — e.g. `notify: rpc getDevices` / `notificationSettings` / `sendNotification`.\n\n## Adding a new backend\n\n1. Create `src/backend/<name>.go` implementing the `Backend` interface (`ID`, `Label`, `Schema`, `ParseTarget`, `Send`) — see `ntfy.go`, `gotify.go`, or `webhook.go` for the shape.\n2. Gate every schema field with `Condition: []sdk.SchemaCondition{{Key: \"service\", Value: ID()}}` so it only renders when the new backend is selected.\n3. Call `backend.Register(new<Name>())` from an `init()` function in the same file.\n4. Bump the version in `package.json`.\n\nNothing outside `src/backend/` needs to change — the registry, the `service` enum, and the\ndispatch logic in `notifier.go` all pick up the new backend automatically.\n\n## Development\n\n```bash\ngo test ./src/...                 # full suite\ngo test ./src/... -race -count=1  # race detector (needs cgo: apt-get install gcc)\nnpm run lint                      # golangci-lint, configured by .golangci.yml\nnpm run format                    # gofmt + go fix\n```\n\nLinting is golangci-lint only. It bundles staticcheck's analyzers (`SA`/`S`/`ST`/`QF`), so running\nthe standalone `staticcheck` binary alongside it only duplicates findings — and, being a separate\ntool, it can't read the path-scoped exclusions in `.golangci.yml`.\n\n```bash\ngo install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@latest\n```\n\n`.golangci.yml` excludes three deliberate idioms, each scoped as narrowly as the linter allows so\nthe check stays live everywhere else: `defer resp.Body.Close()` (errcheck), and — in `_test.go`\nonly — passing a nil `Context` to exercise each backend's `ctx == nil` fallback (SA1012) and the\n`!(a <= b && b <= c)` monotonicity assertions (QF1001).\n\n## License\n\n[MIT](./LICENSE.md).\n","readmeFilename":"README.md"}