@thehammer/danx-dashboard-mcp 0.1.157 → 0.1.159

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
@@ -111,51 +111,6 @@ export async function issueGet(client, args) {
111
111
  board: args.board,
112
112
  });
113
113
  }
114
- // ---------------- brief_list / brief_get_page / brief_set_page ----------------
115
- const BRIEF_BASE_PATH = "/api/brief";
116
- /**
117
- * List the board's named Brief pages via GET /api/brief (DX-2083).
118
- * A bare board-scoped GET, no id — many named pages per board.
119
- */
120
- export async function briefList(client, args = {}) {
121
- return client.request({
122
- method: "GET",
123
- path: "",
124
- basePath: BRIEF_BASE_PATH,
125
- board: args.board,
126
- });
127
- }
128
- /**
129
- * Fetch one Brief page by slug via GET /api/brief/page?slug=
130
- * (DX-2083). A missing row (including a not-yet-created page) reads as the
131
- * empty view — never a 404.
132
- */
133
- export async function briefGetPage(client, args) {
134
- return client.request({
135
- method: "GET",
136
- path: "/page",
137
- basePath: BRIEF_BASE_PATH,
138
- query: { slug: args.slug },
139
- board: args.board,
140
- });
141
- }
142
- /**
143
- * Write one Brief page via PUT /api/brief/page?slug= (DX-2083).
144
- * Optimistic-concurrency `base_hash` with a verbatim 409 passthrough on a
145
- * stale write. `slug` rides the query string (matching the route), never
146
- * the body.
147
- */
148
- export async function briefSetPage(client, args) {
149
- const { slug, board, ...body } = args;
150
- return client.request({
151
- method: "PUT",
152
- path: "/page",
153
- basePath: BRIEF_BASE_PATH,
154
- query: { slug },
155
- body,
156
- board,
157
- });
158
- }
159
114
  export async function issueCreate(client, args, defaultBoard) {
160
115
  // Resolve the target board ONCE: per-call `args.board` override (a
161
116
  // qualified `<repo>:<slug>` id) wins, else the dispatch's env-derived
package/dist/index.js CHANGED
@@ -34,9 +34,6 @@
34
34
  * - issue_attach POST /api/issues/:id/attachments (reads a local file)
35
35
  * - quality_gate_instruction
36
36
  * GET /api/quality-gates/:gate/instruction (DX-3341, not card-scoped)
37
- * - brief_list GET /api/brief
38
- * - brief_get_page GET /api/brief/page (DX-2083 / DX-2484)
39
- * - brief_set_page PUT /api/brief/page (DX-2083 / DX-2484)
40
37
  * - plan_list GET /api/plans (DX-2683)
41
38
  * - plan_get GET /api/plans/:id/full | /api/plans/mine (DX-2727: bare = scalars only, fields= opts in)
42
39
  * - plan_create POST /api/plans
@@ -108,7 +105,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
108
105
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
109
106
  import { z } from "zod";
110
107
  import { DashboardHttpClient } from "./http-client.js";
111
- import { issueAttach, issueChecklist, issueComment, issueCreate, issueDependency, issueEdit, issueGet, issueList, issueProblem, issueQualityGate, issueQualityGateVerdict, issueRetireBranch, issueRetro, issueSolution, issueTransition, issueTriage, briefGetPage, briefList, briefSetPage, failureCategoryCreate, failureCategoryList, failureCategoryUpdate, dispatchTranscriptSearch, planAddArchitectureSection, planAddCard, planAddNote, planAddRecord, planConnect, planCreate, planDeleteArchitectureSection, planDeleteNote, planDeleteRecord, planGet, PLAN_STATUSES, ISSUE_BATCH_GET_MAX, LIST_PAGE_MAX_LIMIT, planGetArchitectureSection, planGetRecord, planList, planRemoveCard, planRename, planReorderArchitectureSection, planUpdateArchitectureSection, planUpdateNote, planUpdateRecord, qualityGateInstruction, resourceFields, } from "./handlers.js";
108
+ import { issueAttach, issueChecklist, issueComment, issueCreate, issueDependency, issueEdit, issueGet, issueList, issueProblem, issueQualityGate, issueQualityGateVerdict, issueRetireBranch, issueRetro, issueSolution, issueTransition, issueTriage, failureCategoryCreate, failureCategoryList, failureCategoryUpdate, dispatchTranscriptSearch, planAddArchitectureSection, planAddCard, planAddNote, planAddRecord, planConnect, planCreate, planDeleteArchitectureSection, planDeleteNote, planDeleteRecord, planGet, PLAN_STATUSES, ISSUE_BATCH_GET_MAX, LIST_PAGE_MAX_LIMIT, planGetArchitectureSection, planGetRecord, planList, planRemoveCard, planRename, planReorderArchitectureSection, planUpdateArchitectureSection, planUpdateNote, planUpdateRecord, qualityGateInstruction, resourceFields, } from "./handlers.js";
112
109
  import { PRIORITY_TIER_WORDS } from "./priority.js";
113
110
  import { fieldTreeSchema } from "./field-tree.js";
114
111
  function readEnvOrDie(name) {
@@ -872,33 +869,6 @@ strictTool("issue_attach", "Attach a LOCAL file to an issue card: `id` (the card
872
869
  .describe("Absolute path to a local file on the dispatch's shared filesystem (must start with `/`)."),
873
870
  ...boardField,
874
871
  }, async (args) => jsonResult(await issueAttach(client, args)));
875
- // ---------------- brief_list ----------------
876
- strictTool("brief_list", "List the board's named Brief pages. Board-scoped; see `board`. Returns `{boardId, pages: [{slug, title, contentHash, sortOrder, updatedAt, updatedBy}]}` — metadata only, no content (use `brief_get_page`). Brief pages are MANY named pages per board (Goals/Architecture/Rules/Caveats tabs), keyed by (board, slug). The reserved `index` slug always exists.", {
877
- ...boardField,
878
- }, async (args) => jsonResult(await briefList(client, args)));
879
- // ---------------- brief_get_page ----------------
880
- strictTool("brief_get_page", 'Fetch one Brief page by slug. Board-scoped; see `board`. Returns `{boardId, slug, title, content, contentHash, sortOrder, updatedAt, updatedBy}` — a missing page reads as the empty view (content/contentHash `""`), not a 404. Before `brief_set_page`, always get immediately first and pass `contentHash` back as `base_hash` — the concurrency guard rejects a stale write.', {
881
- slug: z
882
- .string()
883
- .min(1)
884
- .describe("The page's slug. The reserved `index` slug always exists on every board."),
885
- ...boardField,
886
- }, async (args) => jsonResult(await briefGetPage(client, args)));
887
- // ---------------- brief_set_page ----------------
888
- strictTool("brief_set_page", 'Write one Brief page. Board-scoped; see `board`. Body: `{content, title?, sortOrder?, base_hash?}` — optimistic-concurrency, targeting one named page. `base_hash` must be the `contentHash` from the immediately-prior `brief_get_page` (`""` for a true first write). On mismatch fails loud with `{error: "stale_brief_page", currentHash}` — re-get, re-merge, retry, never overwrite blindly. On success persists, publishes `brief:updated` over SSE, and returns the new view. No delete tool on this surface; the reserved `index` slug is never deletable — removing a non-index page is dashboard-UI-only.', {
889
- slug: z
890
- .string()
891
- .min(1)
892
- .describe("The page's slug. Writing the reserved `index` slug is allowed (it always exists); only deletion of `index` is refused."),
893
- content: z.string(),
894
- title: z.string().optional(),
895
- sortOrder: z.number().optional(),
896
- base_hash: z
897
- .string()
898
- .optional()
899
- .describe('The contentHash last read via brief_get_page ("" for a true first write). Omitted also normalizes to "" server-side, so it only succeeds against an empty/absent page — always get immediately before set.'),
900
- ...boardField,
901
- }, async (args) => jsonResult(await briefSetPage(client, args)));
902
872
  // ---------------- plans (DX-2683) ----------------
903
873
  // THE BINDING ASYMMETRY IS IN THE SCHEMAS, NOT IN PROSE. `plan_get` takes an
904
874
  // optional `plan_id`; `plan_add_record`, `plan_get_record`,
@@ -909,7 +879,7 @@ strictTool("brief_set_page", 'Write one Brief page. Board-scoped; see `board`. B
909
879
  // plan id — and it can only ever bind the caller's own session. `plan_create`
910
880
  // also takes no plan id, but for a different reason: it MAKES a plan rather
911
881
  // than acting on one, so there is no existing plan for an id to name yet.
912
- strictTool("plan_list", "List every plan, and learn which plan THIS session is connected to. Plans are GLOBAL, not board-scoped — a plan is a named, dated set of cards an operator assembled by hand, from any repo. Returns `{plans: [{id, ref, name, createdAt, cardCount, boards, status, signedOffAt, signedOffBy, autoSignOff}], session, sessionListenerAttached}` — `ref` is the plan's short reference (`PLN-<id>`), cite it rather than the bare id. `status` is computed fresh on every read, never stored — except the sign-off pair itself: `awaiting-session` (no live session — a session row isn't released just because a session ended), `planning` (no cards, or only Review/Backlog/terminal ones with ≥1 not Done/Cancelled), `building` (a live session AND ≥1 card ToDo/In Progress or stuck-but-active — Blocked/Needs Help), `awaiting-sign-off` (≥1 card, all Done/Cancelled, but nobody has signed the plan off yet — DX-3519), `complete` (≥1 card, all Done/Cancelled, AND signed off — wins even with no session). `signedOffAt`/`signedOffBy` are `null` until a human (`signedOffBy` = their identity) or the `autoSignOff` toggle (`signedOffBy: 'auto'`) signs the plan off; sign-off itself is a human-only write, not exposed through this MCP surface — direct the operator to the dashboard's plan page. Pass `status` to filter. `session` is your own registration (`{sessionId, title, planId, planName, firstSeenAt, lastActiveAt}`) or null outside a Claude Code session; `planId: null` means connected to no plan — `plan_get` to browse, `plan_connect` to bind. `sessionListenerAttached` says whether your event stream is attached (the plugin's plan bridge); false for a few seconds right after connect is normal, false after that means events aren't reaching you — tell the operator. Distinct from the board Brief (`brief_list`).", {
882
+ strictTool("plan_list", "List every plan, and learn which plan THIS session is connected to. Plans are GLOBAL, not board-scoped — a plan is a named, dated set of cards an operator assembled by hand, from any repo. Returns `{plans: [{id, ref, name, createdAt, cardCount, boards, status, signedOffAt, signedOffBy, autoSignOff}], session, sessionListenerAttached}` — `ref` is the plan's short reference (`PLN-<id>`), cite it rather than the bare id. `status` is computed fresh on every read, never stored — except the sign-off pair itself: `awaiting-session` (no live session — a session row isn't released just because a session ended), `planning` (no cards, or only Review/Backlog/terminal ones with ≥1 not Done/Cancelled), `building` (a live session AND ≥1 card ToDo/In Progress or stuck-but-active — Blocked/Needs Help), `awaiting-sign-off` (≥1 card, all Done/Cancelled, but nobody has signed the plan off yet — DX-3519), `complete` (≥1 card, all Done/Cancelled, AND signed off — wins even with no session). `signedOffAt`/`signedOffBy` are `null` until a human (`signedOffBy` = their identity) or the `autoSignOff` toggle (`signedOffBy: 'auto'`) signs the plan off; sign-off itself is a human-only write, not exposed through this MCP surface — direct the operator to the dashboard's plan page. Pass `status` to filter. `session` is your own registration (`{sessionId, title, planId, planName, firstSeenAt, lastActiveAt}`) or null outside a Claude Code session; `planId: null` means connected to no plan — `plan_get` to browse, `plan_connect` to bind. `sessionListenerAttached` says whether your event stream is attached (the plugin's plan bridge); false for a few seconds right after connect is normal, false after that means events aren't reaching you — tell the operator.", {
913
883
  status: z
914
884
  .enum(PLAN_STATUSES)
915
885
  .optional()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thehammer/danx-dashboard-mcp",
3
- "version": "0.1.157",
3
+ "version": "0.1.159",
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",