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.cjs +221 -48
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +215 -36
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -11
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
|
|
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
|
|
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, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
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
|
|
474
|
-
|
|
475
|
-
|
|
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 (
|
|
478
|
-
const cells =
|
|
479
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|