@thehammer/danx-dashboard-mcp 0.1.84 → 0.1.85
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/dist/listen.js +42 -0
- package/package.json +1 -1
package/dist/listen.js
CHANGED
|
@@ -122,6 +122,32 @@ export function invalidEventReason(value) {
|
|
|
122
122
|
}
|
|
123
123
|
return null;
|
|
124
124
|
}
|
|
125
|
+
// DX-2935 — the operator retracted a problem's answer with no new one yet.
|
|
126
|
+
case "problem_unanswered": {
|
|
127
|
+
const problem = d.problem;
|
|
128
|
+
if (!isRecord(problem) || typeof problem.id !== "number" || !isCappedText(problem.statement)) {
|
|
129
|
+
return "detail.problem is not {id, statement}";
|
|
130
|
+
}
|
|
131
|
+
return typeof d.decision_id === "number" ? null : "detail.decision_id is not a number";
|
|
132
|
+
}
|
|
133
|
+
// DX-2935 — the operator retracted a problem's answer AND recorded a new
|
|
134
|
+
// one, in one transaction — same either/or solution/freeform shape
|
|
135
|
+
// `solution_answered` carries, plus which decision was retracted.
|
|
136
|
+
case "problem_answer_changed": {
|
|
137
|
+
const problem = d.problem;
|
|
138
|
+
if (!isRecord(problem) || typeof problem.id !== "number" || !isCappedText(problem.statement)) {
|
|
139
|
+
return "detail.problem is not {id, statement}";
|
|
140
|
+
}
|
|
141
|
+
if (typeof d.retracted_decision_id !== "number")
|
|
142
|
+
return "detail.retracted_decision_id is not a number";
|
|
143
|
+
if (typeof d.decision_id !== "number")
|
|
144
|
+
return "detail.decision_id is not a number";
|
|
145
|
+
if (d.solution === null)
|
|
146
|
+
return isCappedText(d.freeform) ? null : "detail.freeform is not capped text";
|
|
147
|
+
if (!isRecord(d.solution) || typeof d.solution.title !== "string")
|
|
148
|
+
return "detail.solution is not {title, note}";
|
|
149
|
+
return d.solution.note === null || isCappedText(d.solution.note) ? null : "detail.solution.note is not capped text";
|
|
150
|
+
}
|
|
125
151
|
case "blocked":
|
|
126
152
|
return isCappedText(d.reason) ? null : "detail.reason is not capped text";
|
|
127
153
|
default:
|
|
@@ -160,6 +186,22 @@ function describe(event) {
|
|
|
160
186
|
const problem = d.problem;
|
|
161
187
|
return `${event.actor} opened a problem: ${quoted(problem.statement)}`;
|
|
162
188
|
}
|
|
189
|
+
case "problem_unanswered": {
|
|
190
|
+
// DX-2935 — MUST read as "a previous answer was withdrawn", never as a
|
|
191
|
+
// brand-new problem: a connected session that already acted on the
|
|
192
|
+
// retracted answer has to stop, not treat this as fresh work to start.
|
|
193
|
+
const problem = d.problem;
|
|
194
|
+
return `${event.actor} retracted the answer to ${quoted(problem.statement)}`;
|
|
195
|
+
}
|
|
196
|
+
case "problem_answer_changed": {
|
|
197
|
+
// DX-2935 — ONE line for the whole retract-and-reanswer (never two
|
|
198
|
+
// separate events), naming the statement so a listener with several
|
|
199
|
+
// open questions knows which one just moved.
|
|
200
|
+
const problem = d.problem;
|
|
201
|
+
const solution = d.solution;
|
|
202
|
+
const now = solution === null ? quoted(d.freeform) : `"${solution.title}"`;
|
|
203
|
+
return `${event.actor} changed the answer to ${quoted(problem.statement)}: now ${now}`;
|
|
204
|
+
}
|
|
163
205
|
case "blocked":
|
|
164
206
|
return `${event.actor} blocked the card: ${quoted(d.reason)}`;
|
|
165
207
|
case "unblocked":
|
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.85",
|
|
4
4
|
"description": "Stdio MCP server wrapping danxbot's dashboard /api/issues/* normalized DB-backed HTTP routes for dispatched agents (DX-704 Phase 2).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|