@adonis-agora/durable-dashboard 0.8.0 → 0.8.2
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.
- package/CHANGELOG.md +12 -0
- package/dist/spa/assets/index-BEk3-95l.js +16 -0
- package/dist/spa/assets/index-BEk3-95l.js.map +1 -0
- package/dist/spa/index.html +1 -1
- package/package.json +3 -3
- package/skills/durable-observability/SKILL.md +39 -11
- package/dist/spa/assets/index-DdB9zxuX.js +0 -16
- package/dist/spa/assets/index-DdB9zxuX.js.map +0 -1
package/dist/spa/index.html
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
rel="stylesheet"
|
|
11
11
|
/>
|
|
12
12
|
<title>durable · control plane</title>
|
|
13
|
-
<script type="module" crossorigin src="/__DURABLE_DASHBOARD__/assets/index-
|
|
13
|
+
<script type="module" crossorigin src="/__DURABLE_DASHBOARD__/assets/index-BEk3-95l.js"></script>
|
|
14
14
|
<link rel="stylesheet" crossorigin href="/__DURABLE_DASHBOARD__/assets/index-6nmSTfT7.css">
|
|
15
15
|
</head>
|
|
16
16
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adonis-agora/durable-dashboard",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2",
|
|
4
4
|
"description": "Control-plane console (runs, step timeline, workflow graph, retry/cancel/fix-and-replay) for @adonis-agora/durable — a React SPA served by a thin AdonisJS provider. Part of the Agora ecosystem.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"@base-ui/react": "1.9.0",
|
|
42
42
|
"@tailwindcss/postcss": "4.3.3",
|
|
43
43
|
"@tanstack/intent": "0.5.6",
|
|
44
|
-
"@tanstack/react-query": "5.104.
|
|
44
|
+
"@tanstack/react-query": "5.104.5",
|
|
45
45
|
"@tanstack/react-virtual": "3.14.21",
|
|
46
46
|
"@testing-library/dom": "10.4.2",
|
|
47
47
|
"@testing-library/react": "16.3.3",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"@xyflow/react": "12.12.0",
|
|
53
53
|
"class-variance-authority": "0.7.1",
|
|
54
54
|
"clsx": "2.1.1",
|
|
55
|
-
"happy-dom": "21.0.
|
|
55
|
+
"happy-dom": "21.0.4",
|
|
56
56
|
"jsdom": "30.1.3",
|
|
57
57
|
"react": "19.3.1",
|
|
58
58
|
"react-dom": "19.3.1",
|
|
@@ -52,9 +52,11 @@ export default defineConfig({
|
|
|
52
52
|
})
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
-
The default `authorize`
|
|
56
|
-
equal to `DURABLE_DASHBOARD_TOKEN
|
|
57
|
-
|
|
55
|
+
The default `authorize` fails closed in **every** environment: it requires a
|
|
56
|
+
bearer token equal to `DURABLE_DASHBOARD_TOKEN`, denying everything when that
|
|
57
|
+
env var is unset. Open it up explicitly with `dashboardAuth`, your own
|
|
58
|
+
`authorize`, or (local dev only) `allowUnauthenticated: true`.
|
|
59
|
+
The console mutates runs — always front it with a real guard beyond local dev.
|
|
58
60
|
|
|
59
61
|
## Core patterns
|
|
60
62
|
|
|
@@ -156,6 +158,25 @@ export default defineConfig({
|
|
|
156
158
|
})
|
|
157
159
|
```
|
|
158
160
|
|
|
161
|
+
Every bridge (`collectMetrics`, `attachDurableMetrics`, `attachDurableOtel`, the
|
|
162
|
+
diagnostics bridge Telescope reads) handles only the events its own instance
|
|
163
|
+
produced; another pod's events, re-delivered over the control plane, are skipped
|
|
164
|
+
(`isRemoteEvent(event)`), so a fleet counts and traces each event once.
|
|
165
|
+
|
|
166
|
+
The mounted dashboard also serves `GET <path>/api/metrics` (these counters plus
|
|
167
|
+
`durable_pending_runs` / `durable_running_runs` / `durable_dead_runs` and
|
|
168
|
+
per-group `durable_group_queue_depth` / `durable_group_live_workers` gauges),
|
|
169
|
+
`GET <path>/api/runs/:id/events/:key` (the latest `ctx.setEvent` value, through
|
|
170
|
+
`redact.checkpoint`) and `POST <path>/api/webhooks/:token` (resumes a run parked
|
|
171
|
+
on a `ctx.webhook()`; `wh:` tokens only, behind the console's guard like every
|
|
172
|
+
route — a callback landing before the run waits is buffered `202 { buffered: true }`
|
|
173
|
+
for a live run that has not consumed it yet, consumed by the later `wait()`;
|
|
174
|
+
unknown, terminal or duplicate tokens answer `404` and buffer nothing).
|
|
175
|
+
|
|
176
|
+
Inside a step, a helper that was never handed the logger records through
|
|
177
|
+
`currentStep()?.info(...)` (from `@adonis-agora/durable`; `undefined` outside a
|
|
178
|
+
step).
|
|
179
|
+
|
|
159
180
|
Live-tail one run over SSE:
|
|
160
181
|
`new EventSource('/durable/api/runs/${runId}/stream')`.
|
|
161
182
|
Source: `docs/observability/events-and-interceptors.mdx`,
|
|
@@ -169,7 +190,7 @@ Register the extension once and workflows appear next to requests/queries/jobs:
|
|
|
169
190
|
import { durableTelescopeExtension } from '@adonis-agora/durable/telescope'
|
|
170
191
|
|
|
171
192
|
export default defineConfig({
|
|
172
|
-
extensions: [durableTelescopeExtension({ runHref: '/durable/
|
|
193
|
+
extensions: [durableTelescopeExtension({ runHref: '/durable#/run/{runId}' })],
|
|
173
194
|
})
|
|
174
195
|
```
|
|
175
196
|
|
|
@@ -177,18 +198,22 @@ Rollups (success rate, throughput, duration percentiles, top failures) come from
|
|
|
177
198
|
captured entries bounded by Telescope's prune window; current-state gauges
|
|
178
199
|
(dead/suspended/running/pending NOW) read live from the store via
|
|
179
200
|
`engine.countRuns` (an exact `COUNT`, falling back to a capped `listRuns`
|
|
180
|
-
listing on stores without it).
|
|
201
|
+
listing on stores without it). The **Worker health** table lists every group
|
|
202
|
+
(STARVED first); the **Workers** table has one row per live instance (mode,
|
|
203
|
+
limit, saturation, RAM/CPU, steps/min, p95, last adjustment; `n/a` = no status
|
|
204
|
+
reported, `—` = nothing measured yet). Copies of one event recorded by several
|
|
205
|
+
pods are collapsed by event + runId + emission instant (`dedupeRunEvents`).
|
|
181
206
|
Per-run actions stay in the durable dashboard. Source:
|
|
182
207
|
`docs/observability/telescope.mdx`.
|
|
183
208
|
|
|
184
209
|
## Common mistakes
|
|
185
210
|
|
|
186
|
-
### HIGH trusting an "empty" dashboard config
|
|
211
|
+
### HIGH trusting an "empty" dashboard config to serve the console
|
|
187
212
|
|
|
188
213
|
Wrong:
|
|
189
214
|
|
|
190
215
|
```ts
|
|
191
|
-
export default defineConfig({}) //
|
|
216
|
+
export default defineConfig({}) // DURABLE_DASHBOARD_TOKEN unset — every route 403s
|
|
192
217
|
```
|
|
193
218
|
|
|
194
219
|
Correct:
|
|
@@ -202,9 +227,11 @@ export default defineConfig({
|
|
|
202
227
|
})
|
|
203
228
|
```
|
|
204
229
|
|
|
205
|
-
Mechanism: the default authorize fails CLOSED in
|
|
206
|
-
var is unset, so every console route 403s and the console looks
|
|
207
|
-
than leaking — either set the token deliberately
|
|
230
|
+
Mechanism: the default authorize fails CLOSED in every environment when the
|
|
231
|
+
token env var is unset, so every console route 403s and the console looks
|
|
232
|
+
broken rather than leaking — either set the token deliberately, configure
|
|
233
|
+
`dashboardAuth`, or override authorize (`allowUnauthenticated: true` is the
|
|
234
|
+
explicit local-dev-only opt-out).
|
|
208
235
|
Source: `docs/observability/dashboard.mdx` ("Authorization").
|
|
209
236
|
|
|
210
237
|
### HIGH making interceptor outputs depend on time, randomness or external state
|
|
@@ -288,4 +315,5 @@ undercounts the fleet and zeroes on every deploy of that pod. Source:
|
|
|
288
315
|
See also: `durable-reliability` — what the events mean operationally; bulk
|
|
289
316
|
cancel + compensate semantics.
|
|
290
317
|
See also: `durable-cluster` — which verbs proxy over the wire on store-less pods
|
|
291
|
-
(`retry-with-input
|
|
318
|
+
(`retry`, `retry-with-input`, `continue` and the value pickers do; signal /
|
|
319
|
+
update / tasks / events / webhooks / schedules answer 404 there).
|