{"_id":"@catchhr/nestjs-bullseye","_rev":"10-1da7fa4cab80e948bfe4d8cdbde328ef","name":"@catchhr/nestjs-bullseye","dist-tags":{"latest":"0.1.7"},"versions":{"0.1.1":{"name":"@catchhr/nestjs-bullseye","version":"0.1.1","keywords":["nestjs","bull","queue","dashboard","redis"],"author":"","license":"MIT","_id":"@catchhr/nestjs-bullseye@0.1.1","maintainers":[{"name":"cvr.lo","email":"carlo@catch-talents.de"}],"dist":{"shasum":"8c056ce5757bda7cb057fd6b6325ade978808267","tarball":"https://registry.npmjs.org/@catchhr/nestjs-bullseye/-/nestjs-bullseye-0.1.1.tgz","fileCount":39,"integrity":"sha512-CB1amQ9/gNyqqQ65cSiUID+F7OpHAXUfjXrbqZ/a6LnmWkugwlWaLRYkLNvjWfQ7zxJLT89o7JFv0mGu8PqT0w==","signatures":[{"sig":"MEQCIB4lxqrdJ+1dMYdXCdWiPxxi/k9gJQXquA7UXXVhMKq6AiBxhHdLvDizbXE5WtlYYZpL8aGLycyqfsHNy7uHI4xo3A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1717206},"main":"./dist/index.js","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"8c72f589e5c0ac7a31dd0c5d39a34e0a1a4bddf6","scripts":{"build":"npm run build:frontend && npm run build:lib","build:lib":"tsc -p tsconfig.build.json","build:frontend":"npm install --prefix frontend && npm run build --prefix frontend","prepublishOnly":"npm run build"},"_npmUser":{"name":"cvr.lo","email":"carlo@catch-talents.de"},"_npmVersion":"11.12.1","description":"Embedded Bull queue dashboard (SPA + REST) for NestJS with Express","directories":{},"_nodeVersion":"24.12.0","dependencies":{"express-basic-auth":"^1.2.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"bull":"^4.16.0","ioredis":"^5.0.0","typescript":"~5.9.3","@types/node":"^22.0.0","@nestjs/bull":"^11.0.0","@nestjs/core":"^11.0.0","@nestjs/common":"^11.0.0","@types/express":"^5.0.0"},"peerDependencies":{"bull":"^4.16.0","express":"^4.21.0 || ^5.0.0","ioredis":"^5.0.0","@nestjs/bull":"^11.0.0","@nestjs/core":"^11.0.0","@nestjs/common":"^11.0.0"},"_npmOperationalInternal":{"tmp":"tmp/nestjs-bullseye_0.1.1_1778233230237_0.2308918978989054","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@catchhr/nestjs-bullseye","version":"0.1.2","keywords":["nestjs","bull","queue","dashboard","redis"],"author":"","license":"MIT","_id":"@catchhr/nestjs-bullseye@0.1.2","maintainers":[{"name":"cvr.lo","email":"carlo@catch-talents.de"}],"homepage":"https://gitlab.com/catch-talents/bullseye#readme","bugs":{"url":"https://gitlab.com/catch-talents/bullseye/issues"},"dist":{"shasum":"0ded443aa40fbf9cd1c20740548d43ad10d8211e","tarball":"https://registry.npmjs.org/@catchhr/nestjs-bullseye/-/nestjs-bullseye-0.1.2.tgz","fileCount":48,"integrity":"sha512-VRn31iu2M+7tFqtpXAvGMzsZ9S1ymwafWKE42LTlm63W2qczKpQZdeRKLdRybIxa60lUV79WyHJUfBUWOVt7gA==","signatures":[{"sig":"MEQCIFIUgISBjc/OOVvzFscUSzz0JgMhSxROkXx00Ajc/mlrAiB2yjcaj0JWMPCj0AGc4i9lDMgKeRsvVP6eq6L5n+0kQw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1848198},"main":"./dist/index.js","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"e4a176deee8bf9b0521e646c778d579051cb78b8","scripts":{"build":"npm run build:frontend && npm run build:lib","build:lib":"tsc -p tsconfig.build.json","build:frontend":"npm install --prefix frontend && npm run build --prefix frontend","prepublishOnly":"npm run build"},"_npmUser":{"name":"cvr.lo","email":"carlo@catch-talents.de"},"repository":{"url":"git+https://gitlab.com/catch-talents/bullseye.git","type":"git"},"_npmVersion":"11.12.1","description":"Embedded Bull queue dashboard (SPA + REST) for NestJS with Express","directories":{},"_nodeVersion":"24.12.0","dependencies":{"express-basic-auth":"^1.2.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"bull":"^4.16.0","bullmq":"^5.0.0","ioredis":"^5.0.0","typescript":"~5.9.3","@types/node":"^22.0.0","@nestjs/bull":"^11.0.0","@nestjs/core":"^11.0.0","@nestjs/common":"^11.0.0","@types/express":"^5.0.0"},"peerDependencies":{"bull":"^4.16.0","bullmq":"^5.0.0","express":"^4.21.0 || ^5.0.0","ioredis":"^5.0.0","@nestjs/bull":"^11.0.0","@nestjs/core":"^11.0.0","@nestjs/common":"^11.0.0"},"peerDependenciesMeta":{"bull":{"optional":true},"bullmq":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/nestjs-bullseye_0.1.2_1778237363052_0.39092337360949125","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@catchhr/nestjs-bullseye","version":"0.1.3","keywords":["nestjs","bull","queue","dashboard","redis"],"author":"","license":"MIT","_id":"@catchhr/nestjs-bullseye@0.1.3","maintainers":[{"name":"cvr.lo","email":"carlo@catch-talents.de"}],"homepage":"https://gitlab.com/catch-talents/bullseye#readme","bugs":{"url":"https://gitlab.com/catch-talents/bullseye/issues"},"dist":{"shasum":"8b6c847683a396947236b6b38868a268fc12d1d3","tarball":"https://registry.npmjs.org/@catchhr/nestjs-bullseye/-/nestjs-bullseye-0.1.3.tgz","fileCount":48,"integrity":"sha512-2G8JlXEjDaOPUnpmWBnthg276hh/RyebeQeSBpTveVW6FC1A73sCs1g2vYW8urv3j51gF7gDM18czq1Yk/diEg==","signatures":[{"sig":"MEUCIBT/9Jat87GvbdHKhLe8WXd40eF1KUYdegMAWzkz5YEtAiEAlDoTxp4e0XgFNloixyywdpDX5KrtwvqIYDlpzxCbsII=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1966298},"main":"./dist/index.js","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"d19dedebf0fdc60aeaca5293ba37a261019208d1","scripts":{"build":"npm run build:frontend && npm run build:lib","build:lib":"tsc -p tsconfig.build.json","build:frontend":"npm install --prefix frontend && npm run build --prefix frontend","prepublishOnly":"npm run build"},"_npmUser":{"name":"cvr.lo","email":"carlo@catch-talents.de"},"repository":{"url":"git+https://gitlab.com/catch-talents/bullseye.git","type":"git"},"_npmVersion":"11.12.1","description":"Embedded Bull queue dashboard (SPA + REST) for NestJS with Express","directories":{},"_nodeVersion":"24.12.0","dependencies":{"express-basic-auth":"^1.2.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"bull":"^4.16.0","bullmq":"^5.0.0","ioredis":"^5.0.0","typescript":"~5.9.3","@types/node":"^22.0.0","@nestjs/bull":"^11.0.0","@nestjs/core":"^11.0.0","@nestjs/common":"^11.0.0","@types/express":"^5.0.0"},"peerDependencies":{"bull":"^4.16.0","bullmq":"^5.0.0","express":"^4.21.0 || ^5.0.0","ioredis":"^5.0.0","@nestjs/bull":"^11.0.0","@nestjs/core":"^11.0.0","@nestjs/common":"^11.0.0"},"peerDependenciesMeta":{"bull":{"optional":true},"bullmq":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/nestjs-bullseye_0.1.3_1778328503495_0.7726133248916744","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"@catchhr/nestjs-bullseye","version":"0.1.4","keywords":["nestjs","bull","queue","dashboard","redis"],"author":"","license":"MIT","_id":"@catchhr/nestjs-bullseye@0.1.4","maintainers":[{"name":"cvr.lo","email":"carlo@catch-talents.de"}],"homepage":"https://gitlab.com/catch-talents/bullseye#readme","bugs":{"url":"https://gitlab.com/catch-talents/bullseye/issues"},"dist":{"shasum":"f3474c178453091e98f3d4b640e4611757707b95","tarball":"https://registry.npmjs.org/@catchhr/nestjs-bullseye/-/nestjs-bullseye-0.1.4.tgz","fileCount":48,"integrity":"sha512-4oLYXbfiIp+LFHzVvuOlamUtxMWrN0m0ifc8LBkuqi0SWtolwpZ77aunkcrHEXjX/cuv8SUcZllFoq1dRRXeYA==","signatures":[{"sig":"MEQCIGiFXw9vYaemW9H58DEx4c/S3vX3/DsV1VXjqo25QN6lAiBtDG3BVriWOScXHjj1YsWw+W1oxK4y2SBKDvMuvWXJGA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1966425},"main":"./dist/index.js","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"64874a908a17fb832d8c414d19deedc49865c7ed","scripts":{"build":"npm run build:frontend && npm run build:lib","build:lib":"tsc -p tsconfig.build.json","build:frontend":"npm install --prefix frontend && npm run build --prefix frontend","prepublishOnly":"npm run build"},"_npmUser":{"name":"cvr.lo","email":"carlo@catch-talents.de"},"repository":{"url":"git+https://gitlab.com/catch-talents/bullseye.git","type":"git"},"_npmVersion":"11.12.1","description":"Embedded Bull queue dashboard (SPA + REST) for NestJS with Express","directories":{},"_nodeVersion":"24.12.0","dependencies":{"express-basic-auth":"^1.2.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"bull":"^4.16.0","bullmq":"^5.0.0","ioredis":"^5.0.0","typescript":"~5.9.3","@types/node":"^22.0.0","@nestjs/bull":"^11.0.0","@nestjs/core":"^11.0.0","@nestjs/common":"^11.0.0","@types/express":"^5.0.0"},"peerDependencies":{"bull":"^4.16.0","bullmq":"^5.0.0","express":"^4.21.0 || ^5.0.0","ioredis":"^5.0.0","@nestjs/bull":"^11.0.0","@nestjs/core":"^11.0.0","@nestjs/common":"^11.0.0"},"peerDependenciesMeta":{"bull":{"optional":true},"bullmq":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/nestjs-bullseye_0.1.4_1781855452714_0.6304910993162651","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"name":"@catchhr/nestjs-bullseye","version":"0.1.5","keywords":["nestjs","bull","queue","dashboard","redis"],"author":"","license":"MIT","_id":"@catchhr/nestjs-bullseye@0.1.5","maintainers":[{"name":"cvr.lo","email":"carlo@catch-talents.de"}],"homepage":"https://gitlab.com/catch-talents/bullseye#readme","bugs":{"url":"https://gitlab.com/catch-talents/bullseye/issues"},"dist":{"shasum":"ea328d563085b24ba926580f26981c6f3aab819c","tarball":"https://registry.npmjs.org/@catchhr/nestjs-bullseye/-/nestjs-bullseye-0.1.5.tgz","fileCount":60,"integrity":"sha512-Bayc/KgDLJWf72loJIJH9dF4C8duePsvIeRrhuUi1f52tgdMrMfzkBmLtAsgr3C9TtE0moOWnSvt93SDIdiF3g==","signatures":[{"sig":"MEYCIQCfhCwS2+vtrTDWmbBcjDfW5iFnK/xChci5hV1Pd5MQewIhALl6mSA0ECkTPO6gWMK8BR+wHn2HUZezhFz0yiF52GN0","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1999529},"main":"./dist/index.js","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"64874a908a17fb832d8c414d19deedc49865c7ed","scripts":{"build":"npm run build:frontend && npm run build:lib","build:lib":"tsc -p tsconfig.build.json","build:frontend":"npm install --prefix frontend && npm run build --prefix frontend","prepublishOnly":"npm run build"},"_npmUser":{"name":"cvr.lo","email":"carlo@catch-talents.de"},"repository":{"url":"git+https://gitlab.com/catch-talents/bullseye.git","type":"git"},"_npmVersion":"11.12.1","description":"Embedded Bull queue dashboard (SPA + REST) for NestJS with Express","directories":{},"_nodeVersion":"24.12.0","dependencies":{"zod":"^4.4.3","express-basic-auth":"^1.2.1","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"bull":"^4.16.0","bullmq":"^5.0.0","ioredis":"^5.0.0","typescript":"~5.9.3","@types/node":"^22.0.0","@nestjs/bull":"^11.0.0","@nestjs/core":"^11.0.0","@nestjs/common":"^11.0.0","@types/express":"^5.0.0"},"peerDependencies":{"bull":"^4.16.0","bullmq":"^5.0.0","express":"^4.21.0 || ^5.0.0","ioredis":"^5.0.0","@nestjs/bull":"^11.0.0","@nestjs/core":"^11.0.0","@nestjs/common":"^11.0.0"},"peerDependenciesMeta":{"bull":{"optional":true},"bullmq":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/nestjs-bullseye_0.1.5_1782296154057_0.96320913171467","host":"s3://npm-registry-packages-npm-production"}},"0.1.6":{"name":"@catchhr/nestjs-bullseye","version":"0.1.6","keywords":["nestjs","bull","queue","dashboard","redis"],"author":"","license":"MIT","_id":"@catchhr/nestjs-bullseye@0.1.6","maintainers":[{"name":"cvr.lo","email":"carlo@catch-talents.de"}],"homepage":"https://gitlab.com/catch-talents/bullseye#readme","bugs":{"url":"https://gitlab.com/catch-talents/bullseye/issues"},"dist":{"shasum":"8c39f5ece9992e2cc65d764dfade4fffa7b15bcb","tarball":"https://registry.npmjs.org/@catchhr/nestjs-bullseye/-/nestjs-bullseye-0.1.6.tgz","fileCount":81,"integrity":"sha512-VcFn70fWUWQmFqXseK7e+E2ur8/XHPCaqCtPiqF/ND3EMhtnggX+JMLBbqGinYA0mAAbyMTDqA5o9ih4eO2dcQ==","signatures":[{"sig":"MEUCIQCRE9uh4Gam3IauQMtfVp2MlEm0ofVjJ6WKhmLB6znnqAIgfDS01phbte34Y3y/PDTMQaIV/tTmGb1YgRISEDpKil0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2054484},"main":"./dist/index.js","types":"./dist/index.d.ts","engines":{"node":">=20"},"gitHead":"b9a5853ab0eb56dbe2f2b83106de18cbb817701b","scripts":{"build":"npm run build:frontend && npm run build:lib","build:lib":"tsc -p tsconfig.build.json","build:frontend":"npm install --prefix frontend && npm run build --prefix frontend","prepublishOnly":"npm run build"},"_npmUser":{"name":"cvr.lo","email":"carlo@catch-talents.de"},"repository":{"url":"git+https://gitlab.com/catch-talents/bullseye.git","type":"git"},"_npmVersion":"11.12.1","description":"Embedded Bull queue dashboard (SPA + REST) for NestJS with Express","directories":{},"_nodeVersion":"24.12.0","dependencies":{"zod":"^4.4.3","express-basic-auth":"^1.2.1","@modelcontextprotocol/sdk":"^1.29.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"bull":"^4.16.5","bullmq":"^5.76.8","express":"^5.2.1","ioredis":"^5.10.1","typescript":"~6.0.3","@types/node":"^25.7.0","@nestjs/bull":"^11.0.4","@nestjs/core":"^11.1.19","@nestjs/common":"^11.1.19","@types/express":"^5.0.6"},"peerDependencies":{"bull":"^4.16.0","bullmq":"^5.0.0","express":"^4.21.0 || ^5.0.0","ioredis":"^5.0.0","@nestjs/bull":"^11.0.0","@nestjs/core":"^11.0.0","@nestjs/common":"^11.0.0"},"peerDependenciesMeta":{"bull":{"optional":true},"bullmq":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/nestjs-bullseye_0.1.6_1782306409091_0.6288977436561427","host":"s3://npm-registry-packages-npm-production"}},"0.1.7":{"name":"@catchhr/nestjs-bullseye","version":"0.1.7","description":"Embedded Bull queue dashboard (SPA + REST) for NestJS with Express","license":"MIT","author":"","repository":{"type":"git","url":"git+https://gitlab.com/catch-talents/bullseye.git"},"publishConfig":{"access":"public"},"keywords":["nestjs","bull","queue","dashboard","redis"],"main":"./dist/index.js","types":"./dist/index.d.ts","scripts":{"build":"npm run build:frontend && npm run build:lib","build:lib":"tsc -p tsconfig.build.json","build:frontend":"npm install --prefix frontend && npm run build --prefix frontend","prepublishOnly":"npm run build"},"peerDependencies":{"@nestjs/bull":"^11.0.0","@nestjs/common":"^11.0.0","@nestjs/core":"^11.0.0","bull":"^4.16.0","bullmq":"^5.0.0","express":"^4.21.0 || ^5.0.0","ioredis":"^5.0.0"},"peerDependenciesMeta":{"bull":{"optional":true},"bullmq":{"optional":true}},"dependencies":{"@modelcontextprotocol/sdk":"^1.29.0","express-basic-auth":"^1.2.1","zod":"^4.4.3"},"devDependencies":{"@nestjs/bull":"^11.0.4","@nestjs/common":"^11.1.19","@nestjs/core":"^11.1.19","@types/express":"^5.0.6","@types/node":"^25.7.0","bull":"^4.16.5","bullmq":"^5.76.8","express":"^5.2.1","ioredis":"^5.10.1","typescript":"~6.0.3"},"engines":{"node":">=20"},"gitHead":"63d1d34aeb3dd933eba509c87b5dae8d1cd38830","_id":"@catchhr/nestjs-bullseye@0.1.7","bugs":{"url":"https://gitlab.com/catch-talents/bullseye/issues"},"homepage":"https://gitlab.com/catch-talents/bullseye#readme","_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-rBEiHmdK3Llo/phnhichXSYrhAM69zGu8DXIBEaRilK1UBqQtPLOygEuVAED7fQ18p1ULj9zOz8Z3Nh55F6gjQ==","shasum":"60da223a8a8cd4bfc8a2406c935008117575815c","tarball":"https://registry.npmjs.org/@catchhr/nestjs-bullseye/-/nestjs-bullseye-0.1.7.tgz","fileCount":81,"unpackedSize":2055943,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCdpkMMkCYJN4qwc9/W93xwAIXd4NfJPSwT0WiF/ZtqJQIhAOp9D7x8jqkzX07oKby9JzrIHhe4n35Un9NnXMnEEqAZ"}]},"_npmUser":{"name":"cvr.lo","email":"carlo@catch-talents.de"},"directories":{},"maintainers":[{"name":"cvr.lo","email":"carlo@catch-talents.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/nestjs-bullseye_0.1.7_1785160394374_0.9010529406921701"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-08T09:40:30.146Z","modified":"2026-07-27T13:53:14.765Z","0.1.0":"2026-05-08T09:34:46.825Z","0.1.1":"2026-05-08T09:40:30.447Z","0.1.2":"2026-05-08T10:49:23.232Z","0.1.3":"2026-05-09T12:08:23.676Z","0.1.4":"2026-06-19T07:50:52.889Z","0.1.5":"2026-06-24T10:15:54.300Z","0.1.6":"2026-06-24T13:06:49.338Z","0.1.7":"2026-07-27T13:53:14.589Z"},"bugs":{"url":"https://gitlab.com/catch-talents/bullseye/issues"},"license":"MIT","homepage":"https://gitlab.com/catch-talents/bullseye#readme","keywords":["nestjs","bull","queue","dashboard","redis"],"repository":{"type":"git","url":"git+https://gitlab.com/catch-talents/bullseye.git"},"description":"Embedded Bull queue dashboard (SPA + REST) for NestJS with Express","maintainers":[{"name":"cvr.lo","email":"carlo@catch-talents.de"}],"readme":"# nestjs-bullseye\n\n> **Work in progress**: This project is currently being developed primarily for internal use at our company.  \n> We’re happy if you try it out and would love to get feedback (issues, suggestions, and PRs are welcome).\n\nEmbedded **web dashboard for [Bull](https://github.com/OptimalBits/bull)** (classic Bull queues) in a **NestJS** app with **Express**. Includes queue/job overviews, repeatable jobs, cross-queue logs, runtime statistics, optional **webhook alerts**, and an interactive **time vs. duration** chart on the jobs screen. The UI ships as **static assets** — no separate service required.\n\n> Targets: **Bull (bull + @nestjs/bull)** and **BullMQ (bullmq)**.\n\n---\n\n## Web UI highlights\n\n- **Dashboard** — Workload tiles and charts (live depth, active-job sampling, performance metrics). Content uses comfortable page inset padding.\n- **Queues & jobs** — Queue list and job table use the **full content width** (edge-to-edge under the header) for dense monitoring.\n- **Time · duration heatmap** (jobs view) — Optional collapsible chart: each job is plotted by finish/process time (X) and processing duration (Y). **Brush-drag** a rectangle to filter the table by both dimensions. **Time preset** (stored in `localStorage`) includes **“All time”** (default): the horizontal axis fits the **currently loaded job slice**; other presets are rolling windows (e.g. last hour) and calendar ranges (today, this week, etc.).\n- **Repeatable jobs**, **cross-queue job log**, and **alerts** — Same inset layout as the dashboard for readable margins.\n\n---\n\n## Install\n\n```bash\nnpm install @catchhr/nestjs-bullseye\n```\n\n### Peer dependencies (install in the host app)\n\nIf your app doesn’t have them yet:\n\n```bash\nnpm install @nestjs/common @nestjs/core @nestjs/bull bull ioredis express\n```\n\n### Why there’s a `.npmrc` in this package\n\nThis repository includes a `.npmrc` with `omit=peer` so `npm install` does **not** pull duplicate copies of `@nestjs/*` or `bull` into this package’s own `node_modules`. That helps avoid DI/runtime issues caused by multiple NestJS instances being resolved at runtime.\n\n> Maintainer docs (build/publish/UI development): see `DEVELOPMENT.md`.\n\n---\n\n## Quick start\n\nImport `BullseyeModule` **after** you configure Bull (`BullModule.forRoot` / `registerQueue`). Use the **same Redis settings and the same `prefix`** as your workers.\n\n### Backend selection (Bull vs BullMQ)\n\n- Default: `backend: 'bull'`\n- BullMQ: set `backend: 'bullmq'` (queues can be discovered via Redis key scanning, or configured explicitly via `queueNames`).\n\n```typescript\nimport { Module } from '@nestjs/common';\nimport { BullModule } from '@nestjs/bull';\nimport { BullseyeModule } from '@catchhr/nestjs-bullseye';\n\n@Module({\n  imports: [\n    BullModule.forRoot({\n      redis: { host: 'localhost', port: 6379 },\n      prefix: 'myapp',\n    }),\n    BullModule.registerQueue({ name: 'email' }),\n    BullseyeModule.forRoot({\n      basePath: '/queue-dashboard',\n      redis: { host: 'localhost', port: 6379 },\n      prefix: 'myapp',\n      backend: 'bull', // or: 'bullmq'\n      queueNames: ['email'], // optional allow-list (recommended in locked-down environments)\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\nDashboard: `http://localhost:3000/queue-dashboard` (adjust the port to your Nest app).\n\n### Async config\n\n```typescript\nBullseyeModule.forRootAsync({\n  imports: [ConfigModule],\n  inject: [ConfigService],\n  useFactory: (config: ConfigService) => ({\n    basePath: '/queue-dashboard',\n    redis: config.get('REDIS_URL'),\n    prefix: config.get('BULL_PREFIX'),\n  }),\n}),\n```\n\n---\n\n## Module options (`BullseyeModuleOptions`)\n\n| Option | Type | Description |\n|--------|------|-------------|\n| `backend` | `'bull' \\| 'bullmq'` | Queue backend implementation (default: `bull`). |\n| `basePath` | `string` | Mount path **without** a trailing slash (SPA + `/api/*`). |\n| `faviconPath` | `string?` | Optional favicon file to serve as `${basePath}/favicon.ico` (absolute or relative to `process.cwd()`). |\n| `redis` | same shape as `BullModule.forRoot` | Must match your workers. |\n| `prefix` | `string?` | Bull key prefix (same as in `BullModule.forRoot`). |\n| `queueNames` | `string[]?` | Fixed allow-list; if omitted, queues can be discovered automatically (see below). |\n| `autoDiscoverQueues` | `boolean` | Default `true`. If `false`, only configured/DI-provided queues are exposed. |\n| `basicAuth` | `{ username, password } \\| null` | HTTP Basic auth for UI and API under `basePath`. |\n| `middleware` | Express middleware \\| `null` | Runs after Basic auth (e.g. additional checks). |\n| `alertsStoragePath` | `string?` | JSON file for alerts (default: `.bullseye-alerts.json` in `process.cwd()`). |\n| `operator` | `BullseyeOperatorProfile \\| null` | Optional sidebar profile (name/contact/avatar); returned via `GET …/api/ui-config`. |\n| `mcp` | `BullseyeMcpOptions \\| null` | Optional embedded MCP server (Streamable HTTP) for AI clients — see below. |\n\nExported token: **`BULLSEYE_OPTIONS`**.\n\n### MCP (Cursor, Claude Desktop, …)\n\nWhen `mcp` is set, Bullseye exposes a **Streamable HTTP** MCP endpoint at `${basePath}${mcp.path}` (default `${basePath}/mcp`). It uses **Bearer token** auth (`Authorization: Bearer <apiKey>`) and is mounted **outside** HTTP Basic auth so programmatic clients do not need dashboard credentials.\n\n```typescript\nBullseyeModule.forRoot({\n  basePath: '/queue-dashboard',\n  redis: { host: 'localhost', port: 6379 },\n  mcp: {\n    path: '/mcp',\n    apiKey: process.env.BULLSEYE_MCP_API_KEY!,\n    readOnly: true, // default — write tools when false (future)\n  },\n}),\n```\n\n**Cursor** (`.cursor/mcp.json` in your app or `~/.cursor/mcp.json`):\n\n```json\n{\n  \"mcpServers\": {\n    \"bullseye\": {\n      \"url\": \"http://localhost:3000/queue-dashboard/mcp\",\n      \"headers\": {\n        \"Authorization\": \"Bearer ${env:BULLSEYE_MCP_API_KEY}\"\n      }\n    }\n  }\n}\n```\n\nRead-only tools: `list_queues`, `list_jobs`, `get_job`, `get_job_log`, `get_runtime_stats`, `list_repeatable_jobs`, `get_redis_metrics`.\n\nDo **not** expose the MCP endpoint publicly. Use a long random `apiKey`, VPN/firewall, and the same network posture as the dashboard.\n\nQueues can be detected via Nest DI (Bull classic) and/or via Redis key scanning (`{prefix}:*:meta`).\n\n---\n\n## Security\n\nDo **not** expose this dashboard publicly without protection. Use `basicAuth`, custom `middleware`, and network controls (VPN / firewall).\n\nIf MCP is enabled, protect `${basePath}/mcp` with a strong `mcp.apiKey` and the same network controls — it is not covered by `basicAuth`.\n\n### Alerts / webhooks\n\n- Config is stored as JSON at `alertsStoragePath` (default: `.bullseye-alerts.json`).\n- Bull events are emitted from the **local** queue instance — typically only when workers run in the **same** NestJS process.\n\n---\n\n## API overview (mounted under `basePath`)\n\n- `GET /api/ui-config`, `GET /api/queues`, `GET /api/repeatable-jobs`, `GET /api/stats/job-runtime`, `GET /api/job-log`\n- `GET/POST /api/alerts`, `PUT/DELETE /api/alerts/:id`, `GET /api/alerts/trigger-types`, `GET /api/alerts/suggested-job-names?queues=a,b`\n- `GET /api/queues/:queueName/jobs`, `GET /api/queues/:queueName/jobs/:jobId`\n- `POST /api/queues/:queueName/jobs` — create a job (body: `{ name?, data, opts? }`, JSON)\n- `POST /api/queues/:queueName/jobs/:jobId/promote` — promote a delayed job to **waiting** (204)\n- `POST /api/queues/:queueName/jobs/:jobId/duplicate` — duplicate a job (body: `{ name?, data?, opts? }`; `opts` replaces the source `opts` after stripping `jobId`/`timestamp`)\n\n---\n\n## License\n\nMIT\n","readmeFilename":"README.md"}