@thehammer/danx-dashboard-mcp 0.1.21 → 0.1.22

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/handlers.js CHANGED
@@ -343,9 +343,16 @@ export async function issueRequiresHuman(client, args) {
343
343
  *
344
344
  * `gate` is a registry name (`plan-dependency` | `plan-architecture` |
345
345
  * `plan-tdd` | `code-test-quality` | `code-architecture` | `code-quality`).
346
- * An unknown gate is a 400 from the server (never a silent no-op). The
347
- * board-level master switch is a separate surface — a gate only RUNS when
348
- * the board enables it AND the card marks it required.
346
+ * An unknown gate is a 400 from the server (never a silent no-op).
347
+ *
348
+ * Board requirement is TRI-STATE per gate, NOT a binary on/off
349
+ * (`board_quality_gate_settings.default_state`): `required` = always runs
350
+ * (this per-card flag is irrelevant); `optional` = ENABLED, runs WHEN this
351
+ * per-card flag is true (per-card opt-in — `optional` is NOT "off");
352
+ * `disabled` = never runs (this flag is inert). So flipping `required:true`
353
+ * here launches the gate when the board state is `required` OR `optional`;
354
+ * it is inert ONLY when the board state is `disabled`. Source of truth:
355
+ * `isGateEffectivelyRequired` in `src/issues/quality-gates/read.ts`.
349
356
  */
350
357
  export async function issueQualityGate(client, args) {
351
358
  return client.request({
package/dist/index.js CHANGED
@@ -175,7 +175,7 @@ server.tool("issue_create", 'Create a fresh card via POST /api/issues. Board-sco
175
175
  required_gates: z
176
176
  .array(z.string().min(1))
177
177
  .optional()
178
- .describe('Optional array of quality-gate names to mark REQUIRED on this card (e.g. ["architecture","tdd"]). A gate only actually runs if the board has that gate ENABLED (master switch) AND it is required on the card. Use this when you (the creating agent) judge the card needs that pre-dispatch review gate; omit for cards that don\'t. Known gates: dependency, architecture, tdd, code. The operator can also toggle these per-card later in the issue drawer.'),
178
+ .describe('Optional array of quality-gate names to mark REQUIRED on this card (e.g. ["architecture","tdd"]). Board requirement is TRI-STATE per gate (`board_quality_gate_settings.default_state`), NOT binary: `required` runs always; `optional` runs WHEN flagged on the card (per-card opt-in `optional` is ENABLED, not off); `disabled` never runs (flag inert). So flagging makes the gate run unless the board state is `disabled`. Use this when you (the creating agent) judge the card needs that pre-dispatch review gate; omit for cards that don\'t. Known gates: dependency, architecture, tdd, code. The operator can also toggle these per-card later in the issue drawer.'),
179
179
  phase_children: z
180
180
  .array(z.object({
181
181
  type: z.enum(NON_EPIC_TYPES),
@@ -290,7 +290,7 @@ server.tool("issue_requires_human", "Set or clear the requires_human dispatch ga
290
290
  ...boardField,
291
291
  }, async (args) => jsonResult(await issueRequiresHuman(client, args)));
292
292
  // ---------------- issue_quality_gate ----------------
293
- server.tool("issue_quality_gate", "Toggle a single card's per-card quality-gate `required` flag via POST /api/issues/:id/quality-gates/:gate {required} — the SAME write the dashboard drawer's Quality Gates tab performs (DX-1181). This is the ONLY post-create way to mark a gate required/not-required: `issue_create` carries `required_gates[]` at birth, and `issue_edit` REJECTS gate keys (400 offending_keys) — without this tool a card created without a gate can never have it turned on by an agent. `gate` is a registry name: `plan-dependency` | `plan-architecture` | `plan-tdd` | `code-test-quality` | `code-architecture` | `code-quality` (the PRE/plan- gates run before the work dispatch; the POST/code- gates block issue_transition complete). Unknown gate → 400 (never a silent no-op); a card with no seeded row for a registered gate → 500 (canonical corruption). NOTE the board-level master switch is separate (the Agents-tab `board_quality_gate_settings`): a gate only RUNS when the board enables it AND the card marks it required — flipping `required` here is necessary but not sufficient if the board has the gate disabled. Returns the hydrated issue. Board-scoped; pass `board` (`<repo>:<slug>`) to target another board.", {
293
+ server.tool("issue_quality_gate", "Toggle a single card's per-card quality-gate `required` flag via POST /api/issues/:id/quality-gates/:gate {required} — the SAME write the dashboard drawer's Quality Gates tab performs (DX-1181). This is the ONLY post-create way to mark a gate required/not-required: `issue_create` carries `required_gates[]` at birth, and `issue_edit` REJECTS gate keys (400 offending_keys) — without this tool a card created without a gate can never have it turned on by an agent. `gate` is a registry name: `plan-dependency` | `plan-architecture` | `plan-tdd` | `code-test-quality` | `code-architecture` | `code-quality` (the PRE/plan- gates run before the work dispatch; the POST/code- gates block issue_transition complete). Unknown gate → 400 (never a silent no-op); a card with no seeded row for a registered gate → 500 (canonical corruption). NOTE board requirement is TRI-STATE per gate (`board_quality_gate_settings.default_state`, the Agents-tab surface), NOT a binary on/off: `required` = gate always runs (this flag irrelevant); `optional` = gate runs WHEN this per-card flag is true (per-card opt-in `optional` is ENABLED, NOT off); `disabled` = never runs (this flag inert). So flipping `required:true` here LAUNCHES the gate when the board state is `required` OR `optional`; it is inert ONLY when the board state is `disabled`. Do not read `optional` as off. (Source of truth: `isGateEffectivelyRequired` in `src/issues/quality-gates/read.ts`.) Returns the hydrated issue. Board-scoped; pass `board` (`<repo>:<slug>`) to target another board.", {
294
294
  id: z.string().min(1),
295
295
  gate: z.enum([
296
296
  "plan-dependency",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thehammer/danx-dashboard-mcp",
3
- "version": "0.1.21",
3
+ "version": "0.1.22",
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",