ai-dev-requirements 0.1.12 → 0.1.13

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/index.mjs CHANGED
@@ -5,7 +5,6 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
5
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
6
6
  import crypto from "node:crypto";
7
7
  import { z } from "zod/v4";
8
-
9
8
  //#region src/utils/map-status.ts
10
9
  const ONES_STATUS_MAP = {
11
10
  to_do: "open",
@@ -41,7 +40,6 @@ function mapOnesPriority(priority) {
41
40
  function mapOnesType(type) {
42
41
  return ONES_TYPE_MAP[type.toLowerCase()] ?? "task";
43
42
  }
44
-
45
43
  //#endregion
46
44
  //#region src/adapters/base.ts
47
45
  /**
@@ -58,7 +56,6 @@ var BaseAdapter = class {
58
56
  this.resolvedAuth = resolvedAuth;
59
57
  }
60
58
  };
61
-
62
59
  //#endregion
63
60
  //#region src/adapters/ones.ts
64
61
  const TASK_DETAIL_QUERY = `
@@ -92,6 +89,26 @@ const TASK_DETAIL_QUERY = `
92
89
  }
93
90
  }
94
91
  `;
92
+ const RELATED_ACTIVITIES_QUERY = `
93
+ query Task($key: Key) {
94
+ task(key: $key) {
95
+ key
96
+ ...RelatedActivities_task1
97
+ }
98
+ }
99
+
100
+ fragment RelatedActivities_task1 on Task {
101
+ relatedActivities {
102
+ uuid
103
+ name
104
+ projectUUID
105
+ project_uuid: projectUUID
106
+ relatedChild
107
+ related_child_uuid: relatedChild
108
+ }
109
+ relatedActivitiesCount
110
+ }
111
+ `;
95
112
  const SEARCH_TASKS_QUERY = `
96
113
  query GROUP_TASK_DATA($groupBy: GroupBy, $groupOrderBy: OrderBy, $orderBy: OrderBy, $filterGroup: [Filter!], $search: Search, $pagination: Pagination, $limit: Int) {
97
114
  buckets(groupBy: $groupBy, orderBy: $groupOrderBy, pagination: $pagination, filter: $search) {
@@ -324,7 +341,7 @@ function extractWikiPageUuidsFromText(text) {
324
341
  return [...uuids];
325
342
  }
326
343
  function parseOnesWikiPageRoute(input) {
327
- if (!input.includes("/wiki/")) return null;
344
+ if (!isOnesWikiUrlInput(input)) return null;
328
345
  const match = (() => {
329
346
  try {
330
347
  const parsed = new URL(input);
@@ -332,7 +349,7 @@ function parseOnesWikiPageRoute(input) {
332
349
  } catch {
333
350
  return input;
334
351
  }
335
- })().match(/\/team\/([^/?#]+)\/space\/[^/?#]+\/page\/([^/?#]+)/);
352
+ })().match(/\/team\/([^/?#]+)\/(?:space\/[^/?#]+\/)?page\/([^/?#]+)/);
336
353
  if (!match?.[1] || !match[2]) return null;
337
354
  return {
338
355
  teamUuid: decodeURIComponent(match[1]),
@@ -340,7 +357,7 @@ function parseOnesWikiPageRoute(input) {
340
357
  };
341
358
  }
342
359
  function isOnesWikiUrlInput(input) {
343
- return input.includes("/wiki/");
360
+ return /\/wiki(?:\/|(?=[#?]|$))/.test(input);
344
361
  }
345
362
  function parseAuthorizeRequestId(location) {
346
363
  try {
@@ -464,22 +481,126 @@ function renderWikiEmbed(block, context) {
464
481
  function escapeWikiTableCell(value) {
465
482
  return value.replace(/\|/g, "\\|").replace(/[ \t]*\n+[ \t]*/g, " ").trim();
466
483
  }
484
+ function escapeWikiHtml(value) {
485
+ return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
486
+ }
487
+ function parseWikiTableSpan(value) {
488
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) return 1;
489
+ return Math.max(Math.trunc(value), 1);
490
+ }
491
+ function buildWikiTableLayout(block) {
492
+ const columnCount = typeof block.cols === "number" && block.cols > 0 ? Math.trunc(block.cols) : 0;
493
+ const children = Array.isArray(block.children) ? block.children.filter((child) => typeof child === "string") : [];
494
+ if (!columnCount || !children.length) return null;
495
+ const hasDeclaredRows = typeof block.rows === "number" && block.rows > 0;
496
+ const initialRowCount = hasDeclaredRows ? Math.trunc(block.rows) : Math.max(Math.ceil(children.length / columnCount), 1);
497
+ const occupied = [];
498
+ const rows = [];
499
+ const ensureRowCount = (count) => {
500
+ while (occupied.length < count) {
501
+ occupied.push(Array.from({ length: columnCount }).fill(false));
502
+ rows.push([]);
503
+ }
504
+ };
505
+ ensureRowCount(initialRowCount);
506
+ let cursor = 0;
507
+ let hasMergedCells = false;
508
+ for (const childId of children) {
509
+ while (true) {
510
+ const row = Math.floor(cursor / columnCount);
511
+ const column = cursor % columnCount;
512
+ ensureRowCount(row + 1);
513
+ if (!occupied[row][column]) break;
514
+ cursor += 1;
515
+ }
516
+ const row = Math.floor(cursor / columnCount);
517
+ const column = cursor % columnCount;
518
+ const requestedRowSpan = parseWikiTableSpan(block[`${childId}_rowSpan`]);
519
+ if (!hasDeclaredRows) ensureRowCount(row + requestedRowSpan);
520
+ const rowSpan = Math.min(requestedRowSpan, occupied.length - row);
521
+ const colSpan = Math.min(parseWikiTableSpan(block[`${childId}_colSpan`]), columnCount - column);
522
+ hasMergedCells ||= rowSpan > 1 || colSpan > 1;
523
+ rows[row].push({
524
+ childId,
525
+ row,
526
+ column,
527
+ rowSpan,
528
+ colSpan
529
+ });
530
+ for (let rowOffset = 0; rowOffset < rowSpan; rowOffset += 1) for (let columnOffset = 0; columnOffset < colSpan; columnOffset += 1) occupied[row + rowOffset][column + columnOffset] = true;
531
+ cursor += 1;
532
+ }
533
+ return {
534
+ columnCount,
535
+ rows,
536
+ hasMergedCells
537
+ };
538
+ }
539
+ function wikiCellContainsTable(value) {
540
+ return asWikiBlocks(value).some((block) => block.type === "table");
541
+ }
542
+ function renderWikiTextRunsHtml(value) {
543
+ if (!Array.isArray(value)) return "";
544
+ return value.map((run) => {
545
+ if (!isRecord(run)) return "";
546
+ const attributes = isRecord(run.attributes) ? run.attributes : {};
547
+ let content = escapeWikiHtml(typeof run.insert === "string" ? run.insert.replace(/\u00A0/g, " ") : "").replace(/\n/g, "<br>");
548
+ if (attributes.code) content = `<code>${content}</code>`;
549
+ if (attributes.bold) content = `<strong>${content}</strong>`;
550
+ if (attributes.italic) content = `<em>${content}</em>`;
551
+ if (attributes.underline) content = `<u>${content}</u>`;
552
+ if (attributes.strike) content = `<s>${content}</s>`;
553
+ const link = typeof attributes.link === "string" ? attributes.link : "";
554
+ return link ? `<a href="${escapeWikiHtml(link)}">${content}</a>` : content;
555
+ }).join("");
556
+ }
557
+ function renderWikiCellHtml(value, document, context) {
558
+ return asWikiBlocks(value).map((block) => renderWikiBlockHtml(block, document, context)).filter(Boolean).join("");
559
+ }
560
+ function renderWikiBlockHtml(block, document, context) {
561
+ if (block.type === "table") {
562
+ const layout = buildWikiTableLayout(block);
563
+ return layout ? renderWikiTableHtml(layout, document, context) : "";
564
+ }
565
+ if (block.type === "embed") return `<p>${escapeWikiHtml(renderWikiEmbed(block, context))}</p>`;
566
+ const text = renderWikiTextRunsHtml(block.text);
567
+ if (!text) return "";
568
+ if (block.type === "list") {
569
+ const tag = block.ordered ? "ol" : "ul";
570
+ return `<${tag}><li>${text}</li></${tag}>`;
571
+ }
572
+ if (block.heading) {
573
+ const level = Math.min(Math.max(Math.trunc(block.heading), 1), 6);
574
+ return `<h${level}>${text}</h${level}>`;
575
+ }
576
+ return `<p>${text}</p>`;
577
+ }
578
+ function renderWikiTableHtml(layout, document, context) {
579
+ return `<table>\n<tbody>\n${layout.rows.map((row) => {
580
+ return `<tr>\n${row.map((cell) => {
581
+ const attributes = [cell.rowSpan > 1 ? `rowspan="${cell.rowSpan}"` : "", cell.colSpan > 1 ? `colspan="${cell.colSpan}"` : ""].filter(Boolean);
582
+ const content = renderWikiCellHtml(document[cell.childId], document, context);
583
+ return `<td${attributes.length ? ` ${attributes.join(" ")}` : ""}>${content}</td>`;
584
+ }).join("\n")}\n</tr>`;
585
+ }).join("\n")}\n</tbody>\n</table>`;
586
+ }
467
587
  function renderWikiCell(value, document, context) {
468
588
  const blocks = asWikiBlocks(value);
469
589
  if (!blocks.length) return "";
470
590
  return blocks.map((block) => renderWikiBlock(block, document, context)).filter(Boolean).join(" ").replace(/[ \t]*\n+[ \t]*/g, " ").trim();
471
591
  }
472
592
  function renderWikiTable(block, document, context) {
473
- const cols = typeof block.cols === "number" && block.cols > 0 ? Math.trunc(block.cols) : 0;
474
- const children = Array.isArray(block.children) ? block.children.filter((child) => typeof child === "string") : [];
475
- if (!cols || !children.length) return "";
593
+ const layout = buildWikiTableLayout(block);
594
+ if (!layout) return "";
595
+ const hasNestedTable = layout.rows.some((row) => row.some((cell) => wikiCellContainsTable(document[cell.childId])));
596
+ if (layout.hasMergedCells || hasNestedTable) return renderWikiTableHtml(layout, document, context);
476
597
  const rows = [];
477
- for (let index = 0; index < children.length; index += cols) {
478
- const cells = children.slice(index, index + cols).map((childId) => escapeWikiTableCell(renderWikiCell(document[childId], document, context)));
479
- while (cells.length < cols) cells.push("");
598
+ for (const row of layout.rows) {
599
+ const cells = Array.from({ length: layout.columnCount }).fill("");
600
+ for (const cell of row) cells[cell.column] = escapeWikiTableCell(renderWikiCell(document[cell.childId], document, context));
480
601
  rows.push(`| ${cells.join(" | ")} |`);
481
602
  }
482
- if (rows.length > 1) rows.splice(1, 0, `| ${Array.from({ length: cols }, () => "---").join(" | ")} |`);
603
+ if (rows.length > 1) rows.splice(1, 0, `| ${Array.from({ length: layout.columnCount }).fill("---").join(" | ")} |`);
483
604
  return rows.join("\n");
484
605
  }
485
606
  function renderWikiBlock(block, document, context) {
@@ -702,6 +823,34 @@ var OnesAdapter = class extends BaseAdapter {
702
823
  }
703
824
  return response.json();
704
825
  }
826
+ async onesql(query, variables, workItemType) {
827
+ const session = await this.login();
828
+ const url = `${this.config.apiBase}/project/api/ones-project/team/${session.teamUuid}/workitems/onesql`;
829
+ const response = await fetch(url, {
830
+ method: "POST",
831
+ headers: {
832
+ "Authorization": `Bearer ${session.accessToken}`,
833
+ "Content-Type": "application/json"
834
+ },
835
+ body: JSON.stringify({
836
+ query,
837
+ variables: [
838
+ variables,
839
+ workItemType,
840
+ null,
841
+ null
842
+ ]
843
+ })
844
+ });
845
+ if (!response.ok) {
846
+ const text = await response.text().catch(() => "");
847
+ throw new Error(`ONES OneSQL error: ${response.status} ${text}`);
848
+ }
849
+ return response.json();
850
+ }
851
+ async fetchRelatedActivities(taskKey) {
852
+ return (await this.onesql(RELATED_ACTIVITIES_QUERY, { key: taskKey }, "Task")).data?.task?.relatedActivities ?? [];
853
+ }
705
854
  async searchTaskByNumber(taskNumber) {
706
855
  const session = await this.login();
707
856
  const url = `${this.config.apiBase}/project/api/project/team/${session.teamUuid}/search?q=${encodeURIComponent(String(taskNumber))}&start=0&limit=10&types=task`;
@@ -731,7 +880,8 @@ var OnesAdapter = class extends BaseAdapter {
731
880
  }
732
881
  async fetchIssueTypes() {
733
882
  if (this.issueTypesCache) return this.issueTypesCache;
734
- this.issueTypesCache = (await this.graphql(ISSUE_TYPES_QUERY, { orderBy: { namePinyin: "ASC" } }, "issueTypes")).data?.issueTypes ?? [];
883
+ const data = await this.graphql(ISSUE_TYPES_QUERY, { orderBy: { namePinyin: "ASC" } }, "issueTypes");
884
+ this.issueTypesCache = data.data?.issueTypes ?? [];
735
885
  return this.issueTypesCache;
736
886
  }
737
887
  async fetchProjects() {
@@ -992,8 +1142,10 @@ var OnesAdapter = class extends BaseAdapter {
992
1142
  }
993
1143
  if (isOnesWikiUrlInput(params.id)) throw new Error("ONES: Unsupported wiki page URL. Expected /wiki/#/team/{teamUuid}/space/{spaceUuid}/page/{wikiUuid}");
994
1144
  const taskRef = await this.resolveTaskRef(params.id);
1145
+ const shouldFetchRelatedActivities = parseDisplayId(params.id.trim()) !== null;
995
1146
  const task = (await this.graphql(TASK_DETAIL_QUERY, { key: taskRef.key }, "Task")).data?.task;
996
1147
  if (!task) throw new Error(`ONES: Task "${params.id}" not found`);
1148
+ const relatedActivities = shouldFetchRelatedActivities ? await this.fetchRelatedActivities(taskRef.key) : [];
997
1149
  const wikiRefs = /* @__PURE__ */ new Map();
998
1150
  for (const wiki of task.relatedWikiPages ?? []) if (!wiki.errorMessage) wikiRefs.set(wiki.uuid, {
999
1151
  title: wiki.title,
@@ -1034,6 +1186,18 @@ var OnesAdapter = class extends BaseAdapter {
1034
1186
  parts.push(`- #${related.number} ${related.name} [${related.issueType?.name}] (${related.status?.name}) — ${assignee}`);
1035
1187
  }
1036
1188
  }
1189
+ if (relatedActivities.length) {
1190
+ parts.push("");
1191
+ parts.push("## Related Work Items");
1192
+ for (const activity of relatedActivities) {
1193
+ const details = [
1194
+ `UUID: ${activity.uuid}`,
1195
+ activity.projectUUID ? `Project: ${activity.projectUUID}` : null,
1196
+ activity.relatedChild ? `Relation: ${activity.relatedChild}` : null
1197
+ ].filter(Boolean);
1198
+ parts.push(`- ${activity.name} (${details.join(", ")})`);
1199
+ }
1200
+ }
1037
1201
  if (task.parent?.uuid) {
1038
1202
  parts.push("");
1039
1203
  parts.push("## Parent Task");
@@ -1064,7 +1228,12 @@ var OnesAdapter = class extends BaseAdapter {
1064
1228
  parts.push(detailText);
1065
1229
  }
1066
1230
  const wikiAttachments = wikiContents.flatMap((wiki) => wiki.attachments);
1067
- return toRequirement(task, parts.join("\n"), wikiAttachments);
1231
+ const req = toRequirement(task, parts.join("\n"), wikiAttachments);
1232
+ req.raw = {
1233
+ ...req.raw,
1234
+ relatedActivities
1235
+ };
1236
+ return req;
1068
1237
  }
1069
1238
  /**
1070
1239
  * Search tasks assigned to current user via GraphQL.
@@ -1367,7 +1536,6 @@ var OnesAdapter = class extends BaseAdapter {
1367
1536
  };
1368
1537
  }
1369
1538
  };
1370
-
1371
1539
  //#endregion
1372
1540
  //#region src/adapters/index.ts
1373
1541
  const ADAPTER_MAP = { ones: OnesAdapter };
@@ -1379,7 +1547,6 @@ function createAdapter(sourceType, config, resolvedAuth) {
1379
1547
  if (!AdapterClass) throw new Error(`Unsupported source type: "${sourceType}". Supported: ${Object.keys(ADAPTER_MAP).join(", ")}`);
1380
1548
  return new AdapterClass(sourceType, config, resolvedAuth);
1381
1549
  }
1382
-
1383
1550
  //#endregion
1384
1551
  //#region src/config/loader.ts
1385
1552
  const AuthSchema = z.discriminatedUnion("type", [
@@ -1537,7 +1704,6 @@ function loadConfig(startDir) {
1537
1704
  configPath
1538
1705
  };
1539
1706
  }
1540
-
1541
1707
  //#endregion
1542
1708
  //#region src/tools/add-manhour.ts
1543
1709
  const AddManhourSchema = z.object({
@@ -1573,7 +1739,6 @@ function formatAddManhourResult(result) {
1573
1739
  `- **Description**: ${result.description}`
1574
1740
  ].join("\n");
1575
1741
  }
1576
-
1577
1742
  //#endregion
1578
1743
  //#region src/tools/get-issue-detail.ts
1579
1744
  const GetIssueDetailSchema = z.object({
@@ -1648,7 +1813,6 @@ function formatIssueDetail(detail) {
1648
1813
  else lines.push("_No description_");
1649
1814
  return lines.join("\n");
1650
1815
  }
1651
-
1652
1816
  //#endregion
1653
1817
  //#region src/tools/get-related-issues.ts
1654
1818
  const GetRelatedIssuesSchema = z.object({
@@ -1689,7 +1853,6 @@ function formatRelatedIssues(issues) {
1689
1853
  }
1690
1854
  return lines.join("\n");
1691
1855
  }
1692
-
1693
1856
  //#endregion
1694
1857
  //#region src/tools/get-requirement.ts
1695
1858
  const GetRequirementSchema = z.object({
@@ -1768,7 +1931,6 @@ function formatRequirement(req) {
1768
1931
  }
1769
1932
  return lines.join("\n");
1770
1933
  }
1771
-
1772
1934
  //#endregion
1773
1935
  //#region src/tools/get-testcases.ts
1774
1936
  const GetTestcasesSchema = z.object({
@@ -1820,7 +1982,6 @@ function formatTestcases(result) {
1820
1982
  }
1821
1983
  return lines.join("\n");
1822
1984
  }
1823
-
1824
1985
  //#endregion
1825
1986
  //#region src/tools/list-sources.ts
1826
1987
  async function handleListSources(adapters, config) {
@@ -1846,7 +2007,6 @@ async function handleListSources(adapters, config) {
1846
2007
  text: lines.join("\n")
1847
2008
  }] };
1848
2009
  }
1849
-
1850
2010
  //#endregion
1851
2011
  //#region src/tools/search-requirements.ts
1852
2012
  const SearchRequirementsSchema = z.object({
@@ -1887,7 +2047,6 @@ async function handleSearchRequirements(input, adapters, defaultSource) {
1887
2047
  text: lines.join("\n")
1888
2048
  }] };
1889
2049
  }
1890
-
1891
2050
  //#endregion
1892
2051
  //#region src/tools/update-task-plan-dates.ts
1893
2052
  const DateSchema = z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Expected YYYY-MM-DD");
@@ -1921,7 +2080,6 @@ function formatUpdateTaskPlanDatesResult(result) {
1921
2080
  if (result.planEndDate) lines.push(`- **Plan End Date**: ${result.planEndDate}`);
1922
2081
  return lines.join("\n");
1923
2082
  }
1924
-
1925
2083
  //#endregion
1926
2084
  //#region src/index.ts
1927
2085
  /**
@@ -1969,7 +2127,10 @@ async function main() {
1969
2127
  name: "ai-dev-requirements",
1970
2128
  version: "0.1.0"
1971
2129
  });
1972
- server.tool("get_requirement", "Fetch a single requirement/issue by its ID from a configured source (ONES)", GetRequirementSchema.shape, async (params) => {
2130
+ server.registerTool("get_requirement", {
2131
+ description: "Fetch a single requirement/issue by its ID from a configured source (ONES)",
2132
+ inputSchema: GetRequirementSchema.shape
2133
+ }, async (params) => {
1973
2134
  try {
1974
2135
  return await handleGetRequirement(params, adapters, config.config.defaultSource);
1975
2136
  } catch (err) {
@@ -1982,7 +2143,10 @@ async function main() {
1982
2143
  };
1983
2144
  }
1984
2145
  });
1985
- server.tool("search_requirements", "Search for requirements/issues by keywords across a configured source", SearchRequirementsSchema.shape, async (params) => {
2146
+ server.registerTool("search_requirements", {
2147
+ description: "Search for requirements/issues by keywords across a configured source",
2148
+ inputSchema: SearchRequirementsSchema.shape
2149
+ }, async (params) => {
1986
2150
  try {
1987
2151
  return await handleSearchRequirements(params, adapters, config.config.defaultSource);
1988
2152
  } catch (err) {
@@ -1995,7 +2159,7 @@ async function main() {
1995
2159
  };
1996
2160
  }
1997
2161
  });
1998
- server.tool("list_sources", "List all configured requirement sources and their status", {}, async () => {
2162
+ server.registerTool("list_sources", { description: "List all configured requirement sources and their status" }, async () => {
1999
2163
  try {
2000
2164
  return await handleListSources(adapters, config.config);
2001
2165
  } catch (err) {
@@ -2008,7 +2172,10 @@ async function main() {
2008
2172
  };
2009
2173
  }
2010
2174
  });
2011
- server.tool("get_related_issues", "Get pending defect issues (bugs) related to a requirement task. Returns all pending defects grouped by assignee (current user first).", GetRelatedIssuesSchema.shape, async (params) => {
2175
+ server.registerTool("get_related_issues", {
2176
+ description: "Get pending defect issues (bugs) related to a requirement task. Returns all pending defects grouped by assignee (current user first).",
2177
+ inputSchema: GetRelatedIssuesSchema.shape
2178
+ }, async (params) => {
2012
2179
  try {
2013
2180
  return await handleGetRelatedIssues(params, adapters, config.config.defaultSource);
2014
2181
  } catch (err) {
@@ -2021,7 +2188,10 @@ async function main() {
2021
2188
  };
2022
2189
  }
2023
2190
  });
2024
- server.tool("get_issue_detail", "Get detailed information about a specific issue/defect including description, rich text, and images", GetIssueDetailSchema.shape, async (params) => {
2191
+ server.registerTool("get_issue_detail", {
2192
+ description: "Get detailed information about a specific issue/defect including description, rich text, and images",
2193
+ inputSchema: GetIssueDetailSchema.shape
2194
+ }, async (params) => {
2025
2195
  try {
2026
2196
  return await handleGetIssueDetail(params, adapters, config.config.defaultSource);
2027
2197
  } catch (err) {
@@ -2034,7 +2204,10 @@ async function main() {
2034
2204
  };
2035
2205
  }
2036
2206
  });
2037
- server.tool("get_testcases", "Get all test cases for a task by its number (e.g. 302). Searches the testcase library for a matching module and returns all cases with steps.", GetTestcasesSchema.shape, async (params) => {
2207
+ server.registerTool("get_testcases", {
2208
+ description: "Get all test cases for a task by its number (e.g. 302). Searches the testcase library for a matching module and returns all cases with steps.",
2209
+ inputSchema: GetTestcasesSchema.shape
2210
+ }, async (params) => {
2038
2211
  try {
2039
2212
  return await handleGetTestcases(params, adapters, config.config.defaultSource);
2040
2213
  } catch (err) {
@@ -2047,7 +2220,10 @@ async function main() {
2047
2220
  };
2048
2221
  }
2049
2222
  });
2050
- server.tool("add_manhour", "Add a work-hour record to a ONES task, bug, or requirement. Supports task key, uuid, number, or displayId.", AddManhourSchema.shape, async (params) => {
2223
+ server.registerTool("add_manhour", {
2224
+ description: "Add a work-hour record to a ONES task, bug, or requirement. Supports task key, uuid, number, or displayId.",
2225
+ inputSchema: AddManhourSchema.shape
2226
+ }, async (params) => {
2051
2227
  try {
2052
2228
  return await handleAddManhour(params, adapters, config.config.defaultSource);
2053
2229
  } catch (err) {
@@ -2060,7 +2236,10 @@ async function main() {
2060
2236
  };
2061
2237
  }
2062
2238
  });
2063
- server.tool("update_task_plan_dates", "Update plan start and/or plan end dates for a ONES task, bug, or requirement. Supports task key, uuid, number, or displayId.", UpdateTaskPlanDatesSchema.shape, async (params) => {
2239
+ server.registerTool("update_task_plan_dates", {
2240
+ description: "Update plan start and/or plan end dates for a ONES task, bug, or requirement. Supports task key, uuid, number, or displayId.",
2241
+ inputSchema: UpdateTaskPlanDatesSchema.shape
2242
+ }, async (params) => {
2064
2243
  try {
2065
2244
  return await handleUpdateTaskPlanDates(params, adapters, config.config.defaultSource);
2066
2245
  } catch (err) {
@@ -2080,7 +2259,7 @@ main().catch((err) => {
2080
2259
  console.error("[requirements-mcp] Fatal error:", err);
2081
2260
  process.exit(1);
2082
2261
  });
2083
-
2084
2262
  //#endregion
2085
- export { };
2263
+ export {};
2264
+
2086
2265
  //# sourceMappingURL=index.mjs.map