@thehammer/danx-dashboard-mcp 0.1.187 → 0.1.188
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/README.md +1 -1
- package/dist/bridge.js +4 -0
- package/dist/listen.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -43,7 +43,7 @@ CLAUDE_CODE_SESSION_ID=<session> npx -y @thehammer/danx-dashboard-mcp@<version>
|
|
|
43
43
|
- **No client-side reach check (DX-2920).** `bridge` used to prove board reach itself, before ever opening the stream (`GET /api/plans/mine?fields=cards` + a per-board `GET /api/issues/:id/problems`). That check is DELETED. The dashboard briefly enforced the identical requirement server-side (DX-2863: refusing a mint or stream admission with `403 issuer_cannot_read_plan_boards`, and ending a live stream `{"reason":"scope_narrowed","boards":[…]}`), but DX-3468 removed that mechanism too — DX-3409 made every credential team-bound, so a plan session's issuer and every board its connected plan covers are always in the same team, and the check could never fire any more. `bridge` no longer independently verifies board reach at all, client- or server-side. Once a ticket is minted, `bridge` emits, once, `{"type":"ready"}` — no `boards` field, since reach is no longer proven client-side.
|
|
44
44
|
- **Ticket.** `bridge` mints the session's listener ticket (`POST /api/plan-sessions/me/stream-ticket`, 10 s timeout) and keeps it in the process. A ticket authorizes reading that one session's event stream and nothing else, and is only issued while the session is connected to a plan. Minting a new one ends the previous listener.
|
|
45
45
|
- **Output — JSON Lines.** One `{"type":"event","id":<id|null>,"text":"…"}` per event on the connected plan's cards, where `text` is `[DX-8 "Title" repo:board] newms87 answered "Which rollout order?": chose "Pause E2E" — note: "only this week"`, `… answered "…": "<free-form answer>"`, `… commented: "…"`, `… opened a problem: "…"`, `… blocked the card: "…"`, or `… unblocked the card`. An event it cannot read still produces one, with a `could not read event` text. Nothing for keep-alives, reconnects or re-mints. The session's own writes are never echoed back to it.
|
|
46
|
-
- **Stopping.** Last, one `{"type":"stopped","reason":"…","detail":"…","fix":"…"}` and exit, only on a terminal outcome. `fix` is the remedy shown to the session (`STOP_FIXES` in `src/bridge.ts` — never a log-only hint), so a session that hits a stop it cannot otherwise see still knows what to do about it. Terminal reasons: `no_connection_record` / `credential_unavailable` / `credential_mismatch` (the start-time checks above), `not_connected` (a `409 session_not_connected` at mint OR at stream admission, or a live `end("not_connected")` — all three mapped identically), `unauthorized` (401/403), `mint_refused` (any other non-transient mint refusal), `mint_bad_response`, `superseded` / `replaced` (exit 0 — a newer or replacing connection already serves this session, so `fix` says no action is needed), `revoked`, or `refused` (two freshly minted tickets refused in a row with no more specific classification). A transient mint failure (network, timeout, 408, 429, 5xx) backs off and retries; a lapsed ticket lease re-mints.
|
|
46
|
+
- **Stopping.** Last, one `{"type":"stopped","reason":"…","detail":"…","fix":"…"}` and exit, only on a terminal outcome. `fix` is the remedy shown to the session (`STOP_FIXES` in `src/bridge.ts` — never a log-only hint), so a session that hits a stop it cannot otherwise see still knows what to do about it. Terminal reasons: `no_connection_record` / `credential_unavailable` / `credential_mismatch` (the start-time checks above), `not_connected` (a `409 session_not_connected` at mint OR at stream admission, or a live `end("not_connected")` — all three mapped identically), `plan_archived` (DX-3809 — the plan was archived or deleted while the stream was live; the session is disconnected, and reconnects by hand after a restore), `unauthorized` (401/403), `mint_refused` (any other non-transient mint refusal), `mint_bad_response`, `superseded` / `replaced` (exit 0 — a newer or replacing connection already serves this session, so `fix` says no action is needed), `revoked`, or `refused` (two freshly minted tickets refused in a row with no more specific classification). A transient mint failure (network, timeout, 408, 429, 5xx) backs off and retries; a lapsed ticket lease re-mints.
|
|
47
47
|
- **Reconnect and resume.** A read-idle timeout (three missed keep-alives) turns a silently dead connection into a drop. Capped exponential backoff (1s → 30s) that resets only after a healthy connection, with `Last-Event-ID`, so a dashboard restart replays what was missed and nothing is emitted twice. `--resume-ids` carries the same guarantee across a process restart: the ids already delivered seed the duplicate guard, and the highest is the first `Last-Event-ID`. The dashboard floors that replay at the later of the session's first ticket and when it joined its current plan, so a restart loses nothing and a plan move replays nothing from before the move.
|
|
48
48
|
|
|
49
49
|
## Build + test
|
package/dist/bridge.js
CHANGED
|
@@ -51,6 +51,8 @@
|
|
|
51
51
|
* - `not_connected` the mint, or the stream's admission / keep-alive,
|
|
52
52
|
* answered `session_not_connected` (409 at mint and
|
|
53
53
|
* at admission; `end("not_connected")` once live);
|
|
54
|
+
* - `plan_archived` DX-3809 — the plan was archived or deleted while the
|
|
55
|
+
* stream was live (`end("plan_archived")`);
|
|
54
56
|
* - `unauthorized` the mint answered 401 / 403;
|
|
55
57
|
* - `mint_refused` any other non-transient mint refusal (400, 404, …);
|
|
56
58
|
* - `mint_bad_response` a 2xx mint whose body is not a ticket;
|
|
@@ -209,6 +211,7 @@ export const STOP_FIXES = {
|
|
|
209
211
|
credential_unavailable: "fix the credential this session's danx-dashboard MCP server declares, then call plan_connect again",
|
|
210
212
|
credential_mismatch: "restart this Claude Code session so its MCP server and its bridge pick up the same credential, then call plan_connect again",
|
|
211
213
|
not_connected: "call plan_connect to connect this session to a plan",
|
|
214
|
+
plan_archived: "the plan was archived or deleted, so this session was disconnected; ask the operator to restore it, then call plan_connect again",
|
|
212
215
|
unauthorized: "give this session's danx-dashboard MCP server a dashboard credential that is accepted, then call plan_connect again",
|
|
213
216
|
mint_refused: "check that this session is connected to a plan on the dashboard its MCP server points at, then call plan_connect again",
|
|
214
217
|
mint_bad_response: "check that DANXBOT_DASHBOARD_URL for this session's MCP server points at a danxbot dashboard",
|
|
@@ -516,6 +519,7 @@ function classifyAdmissionRefusal(refusal) {
|
|
|
516
519
|
const EXIT_NEVER_RESTART_LIST = [
|
|
517
520
|
"no_connection_record",
|
|
518
521
|
"not_connected",
|
|
522
|
+
"plan_archived",
|
|
519
523
|
"superseded",
|
|
520
524
|
"replaced",
|
|
521
525
|
"session_is_worker",
|
package/dist/listen.js
CHANGED
|
@@ -353,7 +353,7 @@ function parseBlock(block) {
|
|
|
353
353
|
* than passing the raw string through, which is what lets `Outcome`'s
|
|
354
354
|
* `reason` field below be a closed union instead of `string`.
|
|
355
355
|
*/
|
|
356
|
-
const KNOWN_WIRE_END_REASONS = new Set(["superseded", "replaced", "revoked", "not_connected"]);
|
|
356
|
+
const KNOWN_WIRE_END_REASONS = new Set(["superseded", "replaced", "revoked", "not_connected", "plan_archived"]);
|
|
357
357
|
function isKnownWireEndReason(reason) {
|
|
358
358
|
return KNOWN_WIRE_END_REASONS.has(reason);
|
|
359
359
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thehammer/danx-dashboard-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.188",
|
|
4
4
|
"description": "Stdio MCP server fronting danxbot's dashboard API for agents (operator sessions and dispatched workers alike): the generic danxbot_api/danxbot_api_list/danxbot_api_spec tools reach any route the caller's credential may call, plus dedicated agent-specific tools (plan_connect, danxbot_complete, and other per-dispatch lifecycle callbacks) (DX-3465, PLN-11 R-25).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|