bunqueue-dashboard 0.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/CHANGELOG.md +315 -0
  2. package/LICENSE +21 -0
  3. package/README.md +287 -0
  4. package/agent/db.ts +491 -0
  5. package/agent/dbQueryWorker.ts +21 -0
  6. package/agent/index.ts +47 -0
  7. package/agent/logger.ts +23 -0
  8. package/agent/manager.ts +262 -0
  9. package/agent/server.ts +213 -0
  10. package/dist/.vite/manifest.json +578 -0
  11. package/dist/assets/AddJob-DOtZrwc-.js +3 -0
  12. package/dist/assets/AreaChart-DzUXW8u3.js +1 -0
  13. package/dist/assets/Benchmark-BKVE509y.js +1 -0
  14. package/dist/assets/CopilotPanel-Bn8gPZx_.js +152 -0
  15. package/dist/assets/CopyButton-CSjndiY7.js +1 -0
  16. package/dist/assets/Cron-DzeoQTpD.js +1 -0
  17. package/dist/assets/CronManager-CI6wTFbe.js +1 -0
  18. package/dist/assets/Database-Bjkl_O9n.js +3 -0
  19. package/dist/assets/Diagnostics-BUeDbexv.js +1 -0
  20. package/dist/assets/Dlq-BzwhitJI.js +1 -0
  21. package/dist/assets/DlqControl-BUCut0SS.js +1 -0
  22. package/dist/assets/DlqPro-HoeGdD-B.js +1 -0
  23. package/dist/assets/Flows-D9sVq4vd.js +1 -0
  24. package/dist/assets/JobInspector-dB68adRz.js +2 -0
  25. package/dist/assets/Jobs-CAHFY5qa.js +1 -0
  26. package/dist/assets/JobsPro-BqIHonV6.js +1 -0
  27. package/dist/assets/Logs-DjNLXK_r.js +1 -0
  28. package/dist/assets/LogsPro-BPWf8AAv.js +1 -0
  29. package/dist/assets/McpServer-BVxK5LwU.js +22 -0
  30. package/dist/assets/Metrics-Bm_pwxzy.js +1 -0
  31. package/dist/assets/MetricsPro-DTsnXQVd.js +1 -0
  32. package/dist/assets/Overview-O67Y-R5x.js +1 -0
  33. package/dist/assets/Pagination-B-nfZjQZ.js +1 -0
  34. package/dist/assets/QueueControl-BrHXeXPc.js +1 -0
  35. package/dist/assets/QueueDetail-D-C5SXxB.js +1 -0
  36. package/dist/assets/Queues-5tq1o_1I.js +1 -0
  37. package/dist/assets/QueuesOverview-ClZM34rT.js +1 -0
  38. package/dist/assets/S3Backup-BZfckRKX.js +1 -0
  39. package/dist/assets/S3BackupPro-CteU25_J.js +1 -0
  40. package/dist/assets/ServerControl-BSLX2WeV.js +3 -0
  41. package/dist/assets/Settings-BAELEgud.js +1 -0
  42. package/dist/assets/Usage-B_8T34Sp.js +1 -0
  43. package/dist/assets/UsagePro-BhhM0H05.js +1 -0
  44. package/dist/assets/Webhooks-B_qJ0bx1.js +1 -0
  45. package/dist/assets/Workers-N6qIdxg1.js +1 -0
  46. package/dist/assets/WorkersPro-DzjKVhCO.js +1 -0
  47. package/dist/assets/cn-CMFYpumL.js +1 -0
  48. package/dist/assets/connectionStore-DI-LYcct.js +1 -0
  49. package/dist/assets/form-PtDLk33Z.js +1 -0
  50. package/dist/assets/index-ChJpSdwV.js +8 -0
  51. package/dist/assets/index-DNaP_bi8.css +1 -0
  52. package/dist/assets/install-BvB40Zk0.js +3 -0
  53. package/dist/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
  54. package/dist/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
  55. package/dist/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
  56. package/dist/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
  57. package/dist/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  58. package/dist/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  59. package/dist/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
  60. package/dist/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
  61. package/dist/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
  62. package/dist/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
  63. package/dist/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  64. package/dist/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
  65. package/dist/assets/jobActions-CuOdMglt.js +1 -0
  66. package/dist/assets/react-vendor-CHIHtdAC.js +11 -0
  67. package/dist/favicon.svg +27 -0
  68. package/dist/index.html +30 -0
  69. package/package.json +90 -0
  70. package/scripts/embedded.gen.ts +122 -0
  71. package/scripts/serve.ts +92 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,315 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
+ The version is owned by `package.json` (starting at `0.0.1`) and bumped on every
7
+ push to `main`; `.github/workflows/release.yml` tags and publishes `v<version>`
8
+ to match.
9
+
10
+ **Process (see `CLAUDE.md`):** before every push to `main`, record changes under
11
+ `## [Unreleased]` and bump `package.json`'s `version`. For every version, rename
12
+ `[Unreleased]` to the bumped version and start a fresh empty `[Unreleased]`. The
13
+ release workflow publishes the matching version section (or `[Unreleased]`) as
14
+ the GitHub Release body.
15
+
16
+ ## [Unreleased]
17
+
18
+ ## [0.0.14] - 2026-07-03
19
+
20
+ ### Added
21
+ - **npm package: `bunx bunqueue-dashboard`.** The dashboard is now publishable
22
+ to npm as a Bun-first CLI: one command serves the prebuilt SPA, proxies
23
+ `/api/*` to the bunqueue server, and runs the control agent — the same
24
+ `scripts/serve.ts` the standalone binaries compile, running uncompiled
25
+ (verified: SPA, history fallback, proxy, and agent all answer from a tarball
26
+ install). The tarball ships `dist/` + the agent + the embed manifest only;
27
+ runtime dependencies are down to `pino`/`pino-pretty` (the UI libraries are
28
+ build-time and moved to devDependencies). `release.yml` gains an idempotent
29
+ `npm` job: it publishes with `--provenance` iff the `NPM_TOKEN` secret is set
30
+ and the version isn't already on the registry — a missing secret or an
31
+ un-bumped version is a clean skip, never a failure.
32
+
33
+ ## [0.0.13] - 2026-07-03
34
+
35
+ ### Fixed
36
+ - **A page opened in a background tab no longer sits on "Loading…" forever.**
37
+ `usePolledData` paused polling while the tab was hidden — including the very
38
+ first fetch, so a cmd-clicked tab showed a permanent spinner (and the sidebar
39
+ a permanent "connecting") until focused. The first fetch now always runs;
40
+ only the recurring refreshes pause with the Page Visibility API.
41
+ - **Overview / Metrics / Usage / Jobs no longer report 0 completed jobs after a
42
+ server restart.** Their Completed / Failed cards and error rates read the
43
+ `totalCompleted`/`totalFailed` session counters (zeroed on every restart,
44
+ labeled "all time") while the queues visibly held thousands of completed
45
+ jobs. They now read the recorded counts (`stats.completed` + per-queue failed
46
+ sums from `/queues/summary`); the counters that really are per-session
47
+ (pushed/pulled) are now labeled "since restart", and Diagnostics' "Lifetime
48
+ totals" card is renamed "Totals since restart".
49
+ - **"100.00% success rate" is no longer claimed over zero processed jobs.**
50
+ Error/success rates render an em dash until at least one job has completed
51
+ or failed (`errorRate` now returns `null` for an empty denominator).
52
+ - **Jobs Explorer stat cards no longer flash hard zeros while loading** — they
53
+ show placeholders until the overview poll arrives, and the Total card is
54
+ labeled "all queues" so the global numbers aren't read as the selected
55
+ queue's.
56
+ - **Process logs (Server page) no longer show raw ANSI escape codes** — the
57
+ bunqueue banner's `[1m…[0m` color noise is stripped from display, search,
58
+ copy, and download (new `stripAnsi` in `lib/format.ts`).
59
+ - **Environment-variable rows (Server page) get a usable value field.** The
60
+ KEY input swallowed the whole row and the value input collapsed to a sliver:
61
+ `Input` always carries `w-full` and `cn()` does no Tailwind conflict
62
+ resolution, so the `w-2/5`/`flex-1` passed by the editor lost to it. Widths
63
+ now live on wrapper divs.
64
+
65
+ ### Changed
66
+ - **Dead Letter Queue auto-selects the biggest non-empty queue** on first load
67
+ (like DLQ Control) instead of parking on a "Select a queue" prompt.
68
+ - **Flows remembers the flows you've viewed** (locally, up to 8) and offers
69
+ them as one-click chips in the empty state — bunqueue has no "list flows"
70
+ endpoint, so this replaces a dead end with a way back in.
71
+
72
+ ## [0.0.12] - 2026-07-03
73
+
74
+ ### Added
75
+ - **Animated product tour.** A roughly 50-second guided tour on the README (an
76
+ optimized GIF) and on the docs home (an autoplaying, muted, looping MP4, a far
77
+ lighter video so it does not slow the home page), clicking through the
78
+ overview, queues, jobs, the dead-letter queue, flows, the SQLite inspector,
79
+ and the AI Copilot.
80
+
81
+ ## [0.0.11] - 2026-07-03
82
+
83
+ ### Added
84
+ - **Copilot (experimental): an in-dashboard AI assistant.** A chat panel (the
85
+ button in the bottom right) that reads your live queue state and can propose
86
+ actions you confirm before they run. Bring your own model via the Vercel AI
87
+ SDK: Claude (Anthropic), ChatGPT (OpenAI), Gemini (Google), GLM (Z.ai),
88
+ OpenRouter (one key for every model), or any OpenAI-compatible endpoint
89
+ (Groq, Together, a local Ollama or LM Studio). Your API key stays in memory
90
+ for the session only and is never written to disk; the provider and model are
91
+ remembered. Read tools (queues, jobs, DLQ, workers, crons, health) run
92
+ immediately; mutating tools (retry, promote, remove, pause/resume, retry/purge
93
+ DLQ) are gated behind an explicit in-chat confirmation. The whole panel plus
94
+ the AI SDK (~165 KB gz) is lazy-loaded, so it adds nothing to the initial
95
+ bundle. New `docs/guide/copilot` page.
96
+
97
+ ### Changed
98
+ - **Bundle budget now measures the INITIAL load, not every chunk.** The
99
+ `bun run size` gate reads Vite's build manifest and sums the entry chunk plus
100
+ its static imports (currently ~91 KB gz, budget 230 KB), so lazily-loaded
101
+ features (the demo shim, the Copilot) no longer count against it. A separate,
102
+ generous cap on the grand total still guards against a runaway dependency.
103
+
104
+ ## [0.0.10] - 2026-07-03
105
+
106
+ ### Added
107
+ - **Flows: an interactive job-flow DAG.** A new page that draws a job flow as a
108
+ graph, parent to children (solid edges) and dependency edges (dashed), with
109
+ every node coloured by state. Paste any job ID (or use the new **View flow**
110
+ link in the Job Inspector); the page climbs `parentId` to the flow's root, then
111
+ walks `childrenIds` and `dependsOn` client-side (bunqueue has no single
112
+ "get whole flow" endpoint), lays it out with a pure, unit-tested layered-layout
113
+ engine, and lets you click any node to inspect it. 100% frontend, no graph
114
+ library. Demo mode ships a sample flow so the page is populated out of the box.
115
+ New "Flows" nav item (Queues) and a `docs/guide/flows` page.
116
+
117
+ ### Changed
118
+ - **Full-width pages.** Add Job and Settings now fill the content width with a
119
+ two-column layout instead of a narrow centred column, and the Job Inspector
120
+ lookup bar spans the width.
121
+
122
+ ### Fixed
123
+ - **Classic DLQ page no longer crashes.** It rendered the job's `attempts` field
124
+ directly, but the verified DLQ-entry shape makes `attempts` an array, so React
125
+ threw "Objects are not valid as a React child" (a white screen) against both a
126
+ real server and the demo. It now shows the attempt count, and the row key no
127
+ longer relies on a missing `id`.
128
+ - **Job Inspector custom-ID lookup.** A `200` with no `job` (a custom id that
129
+ resolves to nothing) is now treated as "not found" instead of throwing
130
+ `Cannot read properties of undefined (reading 'state')`. Demo mode also answers
131
+ `GET /jobs/custom/:id`, so custom-id lookups work there too.
132
+
133
+ ## [0.0.9] - 2026-07-03
134
+
135
+ ### Added
136
+ - **MCP Server page + docs.** A setup and reference for bunqueue's Model Context
137
+ Protocol server (`bunqueue-mcp`), which lets AI agents (Claude Desktop, Claude
138
+ Code) drive the queue. Copy-able configs for both connection modes (embedded
139
+ via `DATA_PATH`, and TCP via `BUNQUEUE_MODE`/`HOST`/`PORT`/`TOKEN`), plus the
140
+ full capability inventory: 73 tools across 12 categories, 5 resources, and 3
141
+ prompts. New "MCP" item in the Management nav and a `docs/guide/mcp` page.
142
+ Because `bunqueue-mcp` is a separate stdio process launched by the MCP client,
143
+ the page is a guide, not a live monitor.
144
+
145
+ ## [0.0.8] - 2026-07-03
146
+
147
+ ### Added
148
+ - **SEO: JSON-LD structured data** (schema.org) on every docs page, a
149
+ `SoftwareApplication` node on the home and a `TechArticle` + `BreadcrumbList`
150
+ on each content page, all linked to a shared `WebSite` + `Person` graph, so the
151
+ docs are eligible for rich results. Plus `og:locale`, `og:image:alt` /
152
+ `twitter:image:alt`, and explicit `robots` directives (`index, follow,
153
+ max-image-preview:large, max-snippet:-1`).
154
+ - **Enterprise, fluid docs typography.** The docs now use the same variable fonts
155
+ as the app (Inter for text, JetBrains Mono for code), self-hosted with no CDN,
156
+ and a fluid (viewport-scaled) type scale for headings and body copy, with
157
+ optical sizing, Inter stylistic sets, and tabular figures in code and tables.
158
+
159
+ ### Fixed
160
+ - **Demo mode: the Database page no longer crashes** (`Cannot read properties of
161
+ undefined (reading 'toUpperCase')`). The SQLite inspector's `/db/*` endpoints
162
+ now return proper demo fixtures (info, table list, per-table schema and rows,
163
+ and a read-only query result), so the inspector is fully explorable in the demo
164
+ instead of erroring.
165
+ - **Demo mode:** `GET /queues/:q/dlq/stats` now returns a stats-shaped body (it
166
+ was mis-routed to the DLQ-entries fixture, leaving the demo DLQ stat cards
167
+ empty), and the base/`/api` path stripping is anchored to a segment boundary so
168
+ a path like `/apihealth` can't be mis-stripped.
169
+
170
+ ## [0.0.7] - 2026-07-03
171
+
172
+ ### Added
173
+ - **Demo mode.** A bundled fetch/SSE shim answers every bunqueue API call from a
174
+ fixture captured from a real bunqueue 2.8.26 server, so the whole dashboard is
175
+ explorable with no backend: queues, jobs, DLQ, cron, webhooks, and a live
176
+ activity feed that actually animates. A "Live demo" badge marks it. The demo
177
+ code and its fixture load lazily, so they add nothing to the normal bundle.
178
+ - **Live demo hosting.** The GitHub Pages app now ships in demo mode, so
179
+ `https://egeominotti.github.io/bunqueue-dashboard/` is a fully clickable live
180
+ demo. Linked from the README, the docs home, and the Quickstart.
181
+
182
+ ### Changed
183
+ - The GitHub Pages build serves the root app in demo mode (`VITE_DEMO=1`) instead
184
+ of an empty "point it at your server" shell. To drive a real server, build your
185
+ own (Docker / the standalone binary) without `VITE_DEMO`.
186
+
187
+ ## [0.0.6] - 2026-07-03
188
+
189
+ ### Added
190
+ - **Token lock screen.** When the bunqueue server runs with `AUTH_TOKENS` and a
191
+ request comes back `401`, a lock overlay prompts for the bearer token, stores
192
+ it for the session (never persisted to disk, same as before), and dismisses. If
193
+ the token is still rejected, the next poll re-locks. Includes an "Open Settings
194
+ instead" escape. To wire it up, `bq.ts` now emits an `auth:required` event on a
195
+ `401` (and still throws), so the UI can prompt for credentials.
196
+
197
+ ## [0.0.5] - 2026-07-03
198
+
199
+ ### Added
200
+ - **Quickstart.** A dedicated Quickstart page (prerequisites, install, one-command
201
+ run, connecting a server, and next steps), linked from the docs nav and the
202
+ "Getting started" sidebar group, plus a prominent "Quick start" hero action and
203
+ section on the docs home.
204
+
205
+ ## [0.0.4] - 2026-07-03
206
+
207
+ ### Added
208
+ - **Lighthouse CI** on pull requests: performance, accessibility, best-practices,
209
+ and SEO budgets for the built SPA, with the report uploaded to temporary public
210
+ storage. Thresholds are advisory (`warn`) for now; promote to `error` to
211
+ enforce.
212
+
213
+ ### Fixed
214
+ - **Pages deploy timeout** set to the `deploy-pages` action's real maximum
215
+ (600000 ms; the previous 900000 was clamped by GitHub with a warning).
216
+ Documented that a "Deployment failed, try again later" is a transient
217
+ Pages-backend error to re-run, not a config problem.
218
+
219
+ ## [0.0.3] - 2026-07-03
220
+
221
+ ### Added
222
+ - **Command palette (Cmd/Ctrl-K).** Fuzzy-search every page plus a few actions
223
+ (toggle theme, open docs) and jump there, fully keyboard-driven (↑/↓, ↵, esc),
224
+ with an accessible backdrop and a Topbar search trigger. Its command list is
225
+ sourced from the sidebar nav, so new sections appear automatically.
226
+ - **Bundle-size budget** (`bun run size`), enforced in CI: fails the build if the
227
+ total gzipped JavaScript exceeds 230 KB (currently ~162 KB), so a careless
228
+ dependency can't silently bloat the app.
229
+
230
+ ## [0.0.2] - 2026-07-03
231
+
232
+ ### Added
233
+ - **Structured logging with pino + pino-pretty** for the control agent and the
234
+ standalone server (replaces plain `console.log`): pretty and colorized on a
235
+ terminal, newline-delimited JSON in production, level via `LOG_LEVEL`.
236
+ - **Accessibility:** a "Skip to content" link (bypasses the nav for keyboard and
237
+ screen-reader users) and full `prefers-reduced-motion` support.
238
+ - **Community-health files:** `SECURITY.md`, `CONTRIBUTING.md`,
239
+ `CODE_OF_CONDUCT.md`, and bug-report / feature-request issue templates.
240
+ - **CI hardening:** a dependency audit (`bun audit`) and test coverage on every
241
+ run, plus a **CodeQL** SAST workflow.
242
+ - **Supply-chain integrity:** release binaries now ship a `SHA256SUMS` file and a
243
+ signed **build-provenance attestation**; the Docker image gets an **SBOM** and
244
+ a signed provenance attestation (verifiable with `gh attestation verify`).
245
+ - **Full truth-table test** for `jobActions.actionGates` (the job-action gating
246
+ source of truth).
247
+ - **README hero screenshot** and a screenshot gallery.
248
+
249
+ ### Changed
250
+ - **The standalone server binds `127.0.0.1` by default** (`BIND_ADDR=0.0.0.0` to
251
+ expose): the `/api` proxy to bunqueue's admin API is no longer reachable from
252
+ the whole network out of the box.
253
+ - **Dark-theme accent darkened to `#db2777`** so white text on accent buttons and
254
+ badges meets WCAG AA contrast (was 3.5:1).
255
+
256
+ ### Fixed
257
+ - Declared `VITE_BUNQUEUE_AGENT_URL` in the env type definitions (was read
258
+ untyped).
259
+
260
+ ## [0.0.1] - 2026-07-02
261
+
262
+ First tagged release. A web dashboard that fully drives a bunqueue server over
263
+ its public HTTP API plus a small local control agent, with an illustrated
264
+ documentation site.
265
+
266
+ ### Added
267
+ - **Full control surface.** View and drive queues, jobs, the dead-letter queue,
268
+ cron, webhooks, and workers. Every job action is gated by the job's real
269
+ current state (`src/lib/jobActions.ts`) so the UI never offers something the
270
+ server would reject.
271
+ - **Live, not just polled.** Cheap polling plus a Server-Sent-Events stream for
272
+ real-time job activity, with automatic reconnect and rolling throughput,
273
+ latency, and queue-depth charts.
274
+ - **Process lifecycle.** A small local control agent (loopback-bound,
275
+ CORS-locked to an allowlist, optional `AGENT_TOKEN`) starts, stops, and
276
+ restarts the bunqueue process with live logs.
277
+ - **Read-only SQLite inspector** (`/database`): browse tables, schema and
278
+ indexes, page through rows, and run statement-allowlisted, row-capped,
279
+ read-only queries with `EXPLAIN` and CSV/JSON export.
280
+ - **Two API clients by design:** the original `src/lib/api.ts` behind the
281
+ first-generation classic pages, and the complete, shape-verified,
282
+ strict-error-checked `src/lib/bq.ts` behind every Pro control page.
283
+ - **Illustrated documentation site** (VitePress, published to GitHub Pages under
284
+ `/docs/`): a user-first, screenshot-backed page per dashboard section, a
285
+ Mermaid data-flow diagram, local search, and auto-generated
286
+ `llms.txt` / `llms-full.txt`.
287
+ - **Deployment guides:** Docker (Caddy), Kubernetes, PM2, and hosting-platform
288
+ recipes (Vercel, Netlify, Cloudflare Pages, GitHub Pages, Render, Fly.io,
289
+ Railway, Google Cloud Run), plus an overview of the two deployment modes.
290
+ - **SEO on the docs:** `sitemap.xml`, `robots.txt`, per-page canonical links and
291
+ meta descriptions, and Open Graph / Twitter cards.
292
+ - **Docker image** served with Caddy (gzip + zstd, SPA history fallback,
293
+ immutable asset caching), published to the GitHub Container Registry.
294
+ - **CI/CD:** the lint + build + test gate on every push and PR, GitHub Pages
295
+ deploy, multi-arch Docker image, and a Release workflow that cross-compiles
296
+ standalone executables for 5 platforms (the all-in-one SPA + `/api` proxy +
297
+ control agent in one binary).
298
+ - **Custom brand:** a queue-badge logo and favicon, and hand-drawn monoline
299
+ feature icons on the docs home.
300
+
301
+ [Unreleased]: https://github.com/egeominotti/bunqueue-dashboard/compare/v0.0.14...HEAD
302
+ [0.0.14]: https://github.com/egeominotti/bunqueue-dashboard/compare/v0.0.13...v0.0.14
303
+ [0.0.13]: https://github.com/egeominotti/bunqueue-dashboard/compare/v0.0.12...v0.0.13
304
+ [0.0.12]: https://github.com/egeominotti/bunqueue-dashboard/compare/v0.0.11...v0.0.12
305
+ [0.0.11]: https://github.com/egeominotti/bunqueue-dashboard/compare/v0.0.10...v0.0.11
306
+ [0.0.10]: https://github.com/egeominotti/bunqueue-dashboard/compare/v0.0.9...v0.0.10
307
+ [0.0.9]: https://github.com/egeominotti/bunqueue-dashboard/compare/v0.0.8...v0.0.9
308
+ [0.0.8]: https://github.com/egeominotti/bunqueue-dashboard/compare/v0.0.7...v0.0.8
309
+ [0.0.7]: https://github.com/egeominotti/bunqueue-dashboard/compare/v0.0.6...v0.0.7
310
+ [0.0.6]: https://github.com/egeominotti/bunqueue-dashboard/compare/v0.0.5...v0.0.6
311
+ [0.0.5]: https://github.com/egeominotti/bunqueue-dashboard/compare/v0.0.4...v0.0.5
312
+ [0.0.4]: https://github.com/egeominotti/bunqueue-dashboard/compare/v0.0.3...v0.0.4
313
+ [0.0.3]: https://github.com/egeominotti/bunqueue-dashboard/compare/v0.0.2...v0.0.3
314
+ [0.0.2]: https://github.com/egeominotti/bunqueue-dashboard/compare/v0.0.1...v0.0.2
315
+ [0.0.1]: https://github.com/egeominotti/bunqueue-dashboard/releases/tag/v0.0.1
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Egeo Minotti
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,287 @@
1
+ <div align="center">
2
+
3
+ <img src="docs/logo.svg" alt="bunqueue dashboard" width="340" />
4
+
5
+ # bunqueue dashboard
6
+
7
+ **A web dashboard that _fully drives_ a [bunqueue](https://bunqueue.dev) server**, monitor and
8
+ control queues, jobs, DLQ, cron, webhooks, workers, a live activity stream, and the server
9
+ **process lifecycle** (start / stop / restart) from one place.
10
+
11
+ ### [▶ Try the live demo](https://egeominotti.github.io/bunqueue-dashboard/)
12
+
13
+ The full dashboard running on sample data, no server needed.
14
+
15
+ [![CI](https://github.com/egeominotti/bunqueue-dashboard/actions/workflows/ci.yml/badge.svg)](https://github.com/egeominotti/bunqueue-dashboard/actions/workflows/ci.yml)
16
+ [![Deploy to GitHub Pages](https://github.com/egeominotti/bunqueue-dashboard/actions/workflows/pages.yml/badge.svg)](https://github.com/egeominotti/bunqueue-dashboard/actions/workflows/pages.yml)
17
+ [![Docker](https://github.com/egeominotti/bunqueue-dashboard/actions/workflows/docker.yml/badge.svg)](https://github.com/egeominotti/bunqueue-dashboard/actions/workflows/docker.yml)
18
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
19
+ [![Documentation](https://img.shields.io/badge/docs-online-db2777)](https://egeominotti.github.io/bunqueue-dashboard/docs/)
20
+ [![Live demo](https://img.shields.io/badge/live%20demo-online-22c55e)](https://egeominotti.github.io/bunqueue-dashboard/)
21
+ ![Status: Beta](https://img.shields.io/badge/status-beta-f59e0b)
22
+
23
+ ![React 19](https://img.shields.io/badge/React-19-149ECA?logo=react&logoColor=white)
24
+ ![Vite 8](https://img.shields.io/badge/Vite-8-646CFF?logo=vite&logoColor=white)
25
+ ![Bun](https://img.shields.io/badge/Bun-1.3-000?logo=bun&logoColor=white)
26
+ ![TypeScript](https://img.shields.io/badge/TypeScript-strict-3178C6?logo=typescript&logoColor=white)
27
+ ![Biome](https://img.shields.io/badge/Biome-lint%20%2B%20format-60A5FA?logo=biome&logoColor=white)
28
+
29
+ <br />
30
+
31
+ <img src="docs/public/tour.gif" alt="A guided tour of the bunqueue dashboard, clicking through the overview, queues, jobs, the dead-letter queue, flows, the SQLite inspector, and the AI Copilot" width="900" />
32
+
33
+ <sub>A quick tour. <a href="https://egeominotti.github.io/bunqueue-dashboard/">Try it live →</a></sub>
34
+
35
+ <br /><br />
36
+
37
+ <img src="docs/screenshots/overview.png" alt="bunqueue dashboard, real-time overview: health, throughput, per-queue status, and a live activity feed" width="900" />
38
+
39
+ <sub>The Overview page. <a href="https://egeominotti.github.io/bunqueue-dashboard/docs/user-guide">See every screen in the illustrated guide →</a></sub>
40
+
41
+ <details>
42
+ <summary><b>More screenshots</b></summary>
43
+ <br />
44
+ <img src="docs/screenshots/server.png" alt="Server Control, start/stop/restart the bunqueue process with live logs" width="900" />
45
+ <img src="docs/screenshots/jobs.png" alt="Jobs Explorer, filter, inspect, and bulk-action jobs" width="900" />
46
+ <img src="docs/screenshots/database.png" alt="Read-only SQLite inspector, browse tables and run queries" width="900" />
47
+ </details>
48
+
49
+ </div>
50
+
51
+ ---
52
+
53
+ > ⚠️ **Beta.** bunqueue dashboard is under active development, interfaces and
54
+ > behavior may change between releases. Review it before relying on it for
55
+ > unattended production use.
56
+
57
+ ## 📚 Documentation
58
+
59
+ **Full, illustrated docs live at
60
+ [egeominotti.github.io/bunqueue-dashboard/docs](https://egeominotti.github.io/bunqueue-dashboard/docs/).**
61
+
62
+ - **[Illustrated user guide](https://egeominotti.github.io/bunqueue-dashboard/docs/user-guide)**, one detailed, screenshot-backed page per dashboard section.
63
+ - **[Deployment](https://egeominotti.github.io/bunqueue-dashboard/docs/deploy/)**, Docker (Caddy), Kubernetes, PM2, and hosting platforms (Vercel, Netlify, Cloudflare, Fly.io, Render, Cloud Run).
64
+ - **[Architecture](https://egeominotti.github.io/bunqueue-dashboard/docs/architecture)** and **[API mapping](https://egeominotti.github.io/bunqueue-dashboard/docs/api-mapping)**, how it fits together and every endpoint it drives.
65
+ - **[llms.txt](https://egeominotti.github.io/bunqueue-dashboard/docs/llms.txt)**, the whole site as a single file for LLMs.
66
+
67
+ ## Table of contents
68
+
69
+ - [Documentation](#-documentation)
70
+ - [Why](#why)
71
+ - [Features](#features)
72
+ - [Quick start](#quick-start)
73
+ - [Architecture](#architecture)
74
+ - [Configuration](#configuration)
75
+ - [Scripts](#scripts)
76
+ - [Docker](#docker)
77
+ - [Deployment](#deployment)
78
+ - [Testing & quality gate](#testing--quality-gate)
79
+ - [Project structure](#project-structure)
80
+ - [Security](#security)
81
+ - [Contributing](#contributing)
82
+ - [License](#license)
83
+
84
+ ## Why
85
+
86
+ bunqueue exposes a rich HTTP API, but operating it by hand (curl, ad-hoc scripts) is slow and
87
+ error-prone. This dashboard is a **complete operator console**: everything the API can do, plus the
88
+ one thing it can't, managing the server *process*, behind a fast, keyboard-friendly UI.
89
+
90
+ It talks **only** to bunqueue's public HTTP API (`:6790`) and a small local **control agent**. It
91
+ never imports or modifies bunqueue itself, so it tracks any bunqueue server you point it at.
92
+
93
+ ## Features
94
+
95
+ | Area | Where | What you can do |
96
+ | --- | --- | --- |
97
+ | **Home** | Overview | Live health banner, throughput, queue health, recent activity |
98
+ | **Server** | Control ▸ Server | **Start / stop / restart** the server process, edit its config, tail process logs |
99
+ | **Enqueue** | Control ▸ Add Job | Add jobs (single or bulk) with every option |
100
+ | **Inspect** | Control ▸ Job Inspector | Look up any job; promote / retry / discard / cancel / re-prioritize / delay; view data & result |
101
+ | **Queues** | Control ▸ Queue Control | Pause / resume / drain / clean / promote / retry-completed, rate-limit, concurrency, stall & DLQ policy |
102
+ | **Cron** | Control ▸ Cron Manager | Create (cron or interval) and delete schedules |
103
+ | **DLQ** | Control ▸ DLQ | Inspect dead-letter entries, retry one / all, purge |
104
+ | **Webhooks** | Control ▸ Webhooks | Create / enable / delete job-event webhooks |
105
+ | **Ops** | Control ▸ Diagnostics | Health, ping, storage, memory, connections, totals |
106
+ | **Browse** | Queues / Jobs / DLQ / Cron / Metrics / Workers / Logs | Read-only browsing with basic actions |
107
+
108
+ > Every job action is **gated by the job's real state** (`src/lib/jobActions.ts`), so the UI never
109
+ > offers an action the server would reject.
110
+
111
+ ## Quick start
112
+
113
+ **Prerequisites:** [Bun](https://bun.sh) ≥ 1.3 and a reachable bunqueue server (or let the control
114
+ agent start one for you from the **Server** page).
115
+
116
+ ### Run from npm (no clone)
117
+
118
+ ```bash
119
+ bunx bunqueue-dashboard
120
+ ```
121
+
122
+ One command: serves the prebuilt dashboard on http://127.0.0.1:8080, proxies `/api/*` to your
123
+ bunqueue server (`BUNQUEUE_URL`, default `http://localhost:6790`), and runs the control agent on
124
+ `127.0.0.1:6800`. Same env knobs as the standalone binaries: `PORT` · `BIND_ADDR` · `BUNQUEUE_URL` ·
125
+ `AGENT_PORT` · `AGENT_ALLOWED_ORIGINS` · `AGENT_TOKEN` · `BUNQUEUE_START_CMD`.
126
+
127
+ ### Run from source
128
+
129
+ ```bash
130
+ git clone https://github.com/egeominotti/bunqueue-dashboard.git
131
+ cd bunqueue-dashboard
132
+ bun install
133
+ bun start
134
+ ```
135
+
136
+ `bun start` boots **both** the control agent and the dashboard in one terminal and shuts both down
137
+ on `Ctrl-C`:
138
+
139
+ | Service | URL | Role |
140
+ | --- | --- | --- |
141
+ | Dashboard | http://localhost:5273 | The UI (`/api/*` is proxied to `:6790` in dev) |
142
+ | Control agent | http://127.0.0.1:6800 | Starts / stops / restarts the server process |
143
+ | bunqueue server | http://localhost:6790 | Your queue server, started from the **Server** page or run separately |
144
+
145
+ Prefer separate terminals? The individual commands still exist, see [Scripts](#scripts).
146
+
147
+ ## Architecture
148
+
149
+ ```mermaid
150
+ flowchart LR
151
+ subgraph Browser
152
+ UI["Dashboard (React 19 SPA)"]
153
+ end
154
+ subgraph Local
155
+ Agent["Control agent (Bun)<br/>127.0.0.1:6800"]
156
+ Server["bunqueue server<br/>:6790 HTTP · :6789 TCP"]
157
+ end
158
+ UI -- "HTTP: queues, jobs, DLQ, cron…" --> Server
159
+ UI -- "SSE: live activity" --> Server
160
+ UI -- "/control/* start·stop·restart" --> Agent
161
+ Agent -- "spawn / kill process" --> Server
162
+ ```
163
+
164
+ - **Reads** by polling (`usePolledData`) and a Server-Sent Events stream (`useActivityStream`).
165
+ - **Writes** through the same HTTP API, with every mutation shape-verified against the live server.
166
+ - **Process lifecycle**, the one thing HTTP can't do, is delegated to the local control agent.
167
+
168
+ Two HTTP clients coexist on purpose: `src/lib/api.ts` (first-generation view pages) and
169
+ `src/lib/bq.ts` (the complete, shape-verified client used by every `Control ▸ *` page). See
170
+ [`docs/`](docs/README.md) for the full, source-verified reference.
171
+
172
+ ## Configuration
173
+
174
+ All dashboard variables are build-time (`VITE_*`) and can **also** be changed at runtime from the
175
+ in-app **Settings** page. Copy [`.env.example`](.env.example) to `.env` to set defaults.
176
+
177
+ | Variable | Purpose | Default |
178
+ | --- | --- | --- |
179
+ | `VITE_BUNQUEUE_URL` | bunqueue server origin | `/api` (dev proxy → `:6790`) |
180
+ | `VITE_BUNQUEUE_TOKEN` | Bearer token, if the server has `AUTH_TOKENS` set | _none_ |
181
+ | `VITE_BUNQUEUE_AGENT_URL` | Control-agent origin | `http://localhost:6800` |
182
+ | `AGENT_PORT` | Control-agent port | `6800` |
183
+ | `AGENT_ALLOWED_ORIGINS` | Extra browser origins allowed to drive the agent (comma-separated) | dev defaults |
184
+ | `AGENT_TOKEN` | Optional bearer token required on state-changing agent requests | _none_ (off) |
185
+
186
+ ## Scripts
187
+
188
+ | Command | Does |
189
+ | --- | --- |
190
+ | `bun start` | **Agent + dashboard together** (one-command dev) |
191
+ | `bun dev` | Dashboard only (Vite dev server) |
192
+ | `bun run agent` | Control agent only |
193
+ | `bun run build` | Typecheck (`tsc --noEmit`) + production build → `dist/` |
194
+ | `bun run preview` | Preview the production build |
195
+ | `bun run check` | Biome lint + format (the CI gate) |
196
+ | `bun run check:fix` | Biome lint + format with safe fixes applied |
197
+ | `bun test` | Unit + agent-lifecycle tests |
198
+
199
+ ## Docker
200
+
201
+ A multi-stage image builds the SPA with Bun and serves it with Caddy (gzip/zstd, SPA history fallback, immutable asset caching). Published to the GitHub Container Registry on every push.
202
+
203
+ ```bash
204
+ # Pull & run the published image (`edge` tracks main; use `vX.Y.Z`/`latest` after a release)
205
+ docker run --rm -p 8080:80 ghcr.io/egeominotti/bunqueue-dashboard:edge
206
+ # → http://localhost:8080 (set the server URL from the Settings page)
207
+
208
+ # …or build locally, optionally baking in a default server origin
209
+ docker build --build-arg VITE_BUNQUEUE_URL=https://queue.example.com -t bunqueue-dashboard .
210
+ docker run --rm -p 8080:80 bunqueue-dashboard
211
+ ```
212
+
213
+ Tags: `latest` and `vX.Y.Z` on releases, `edge` on `main`.
214
+
215
+ ## Deployment
216
+
217
+ - **Standalone executables**, every [release](https://github.com/egeominotti/bunqueue-dashboard/releases)
218
+ ships self-contained binaries for **Linux (x64/arm64), macOS (x64/arm64) and Windows (x64)**:
219
+ download one file and run it, it serves the dashboard (assets embedded), proxies `/api` to your
220
+ bunqueue server (`BUNQUEUE_URL`, default `:6790`) and includes the control agent.
221
+ ```bash
222
+ ./bunqueue-dashboard-vX.Y.Z-darwin-arm64 # → http://localhost:8080
223
+ PORT=3000 BUNQUEUE_URL=https://queue.example.com ./bunqueue-dashboard-vX.Y.Z-linux-x64
224
+ ```
225
+ - **GitHub Pages**, every push to `main` builds and publishes the static SPA
226
+ (`.github/workflows/pages.yml`). The workflow **attempts** to auto-provision Pages; if the first
227
+ run reports `Get Pages site failed`, enable it once under **Settings ▸ Pages ▸ Source → GitHub
228
+ Actions** (the default `GITHUB_TOKEN` can't create a Pages site on its own). The build sets the
229
+ correct sub-path base and a `404.html` SPA fallback automatically.
230
+ - **Container**, self-host the published `ghcr.io` image behind any reverse proxy.
231
+ - **Static host**, `bun run build` emits a plain `dist/` you can serve from any CDN or static host.
232
+
233
+ Because the deployed build is a static shell, point it at a reachable bunqueue server via
234
+ `VITE_BUNQUEUE_URL` (build time) or the **Settings** page (runtime).
235
+
236
+ ## Testing & quality gate
237
+
238
+ Three commands must be green before a change is considered done, the same checks CI runs:
239
+
240
+ ```bash
241
+ bun run build # tsc --noEmit + vite build
242
+ bun run check # Biome lint + format (production-grade config)
243
+ bun test # unit + agent-lifecycle tests
244
+ ```
245
+
246
+ CI enforces this on every push and pull request. See [Contributing](#contributing).
247
+
248
+ ## Project structure
249
+
250
+ ```
251
+ bunqueue-dashboard/
252
+ ├── .github/workflows/ # CI, Pages deploy, Docker publish, Release
253
+ ├── agent/ # Bun control agent (process lifecycle), server.ts, manager.ts, index.ts
254
+ ├── docker/ # Caddyfile for the container image
255
+ ├── docs/ # source-verified reference (architecture, pages, API mapping, known issues)
256
+ ├── scripts/dev.ts # one-command dev launcher (`bun start`)
257
+ ├── src/
258
+ │ ├── lib/ # api.ts, bq.ts, hooks, formatters, job-action gating
259
+ │ ├── components/ # layout shell, UI kit, Zustand stores
260
+ │ └── pages/ # view pages + Control ▸ * operator pages
261
+ └── test/ # bun test (format, sse, manager, agent lifecycle, s3 store)
262
+ ```
263
+
264
+ Full walkthrough in [`docs/README.md`](docs/README.md).
265
+
266
+ ## Security
267
+
268
+ The control agent can spawn processes, so it is hardened by design (`agent/server.ts`):
269
+
270
+ - Binds **`127.0.0.1` only**.
271
+ - **CORS locked to an allowlist**, `Access-Control-Allow-Origin` is never `*`.
272
+ - Requests carrying a **disallowed `Origin` are rejected (403)** before reaching the process manager, blocking drive-by CSRF from a malicious tab.
273
+ - Optional **`AGENT_TOKEN`** adds a bearer-token gate on state-changing requests.
274
+
275
+ Keep the agent on loopback (or an equivalently trusted network) and set `AGENT_TOKEN` for shared
276
+ machines. See [`docs/known-issues.md`](docs/known-issues.md) for the honest, verified limitations.
277
+
278
+ ## Contributing
279
+
280
+ 1. Keep it **additive**, prefer new files + minimal glue over rewriting existing ones
281
+ (see [`CLAUDE.md`](CLAUDE.md)).
282
+ 2. Make the [gate](#testing--quality-gate) green: `bun run build && bun run check && bun test`.
283
+ 3. Open a PR, the template walks you through the checklist. CI must pass.
284
+
285
+ ## License
286
+
287
+ [MIT](LICENSE) © Egeo Minotti