@shortcut/mcp 0.6.1 → 0.7.0
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.js +141 -264
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -14602,10 +14602,12 @@ class ShortcutClientWrapper {
|
|
|
14602
14602
|
client;
|
|
14603
14603
|
currentUser = null;
|
|
14604
14604
|
userCache;
|
|
14605
|
+
teamCache;
|
|
14605
14606
|
workflowCache;
|
|
14606
14607
|
constructor(client) {
|
|
14607
14608
|
this.client = client;
|
|
14608
14609
|
this.userCache = new Cache;
|
|
14610
|
+
this.teamCache = new Cache;
|
|
14609
14611
|
this.workflowCache = new Cache;
|
|
14610
14612
|
}
|
|
14611
14613
|
async loadMembers() {
|
|
@@ -14617,6 +14619,15 @@ class ShortcutClientWrapper {
|
|
|
14617
14619
|
}
|
|
14618
14620
|
}
|
|
14619
14621
|
}
|
|
14622
|
+
async loadTeams() {
|
|
14623
|
+
if (this.teamCache.isStale) {
|
|
14624
|
+
const response = await this.client.listGroups();
|
|
14625
|
+
const groups = response?.data ?? null;
|
|
14626
|
+
if (groups) {
|
|
14627
|
+
this.teamCache.setMany(groups.map((group) => [group.id, group]));
|
|
14628
|
+
}
|
|
14629
|
+
}
|
|
14630
|
+
}
|
|
14620
14631
|
async loadWorkflows() {
|
|
14621
14632
|
if (this.workflowCache.isStale) {
|
|
14622
14633
|
const response = await this.client.listWorkflows();
|
|
@@ -14672,9 +14683,13 @@ class ShortcutClientWrapper {
|
|
|
14672
14683
|
return workflow;
|
|
14673
14684
|
}
|
|
14674
14685
|
async getTeams() {
|
|
14675
|
-
|
|
14676
|
-
const
|
|
14677
|
-
return
|
|
14686
|
+
await this.loadTeams();
|
|
14687
|
+
const teams = Array.from(this.teamCache.values());
|
|
14688
|
+
return teams;
|
|
14689
|
+
}
|
|
14690
|
+
async getTeamMap(teamIds) {
|
|
14691
|
+
await this.loadTeams();
|
|
14692
|
+
return new Map(teamIds.map((id) => [id, this.teamCache.get(id)]).filter((team) => team[1] !== null));
|
|
14678
14693
|
}
|
|
14679
14694
|
async getTeam(teamPublicId) {
|
|
14680
14695
|
const response = await this.client.getGroup(teamPublicId);
|
|
@@ -14726,7 +14741,7 @@ class ShortcutClientWrapper {
|
|
|
14726
14741
|
return milestone;
|
|
14727
14742
|
}
|
|
14728
14743
|
async searchStories(query) {
|
|
14729
|
-
const response = await this.client.searchStories({ query, page_size: 25, detail: "
|
|
14744
|
+
const response = await this.client.searchStories({ query, page_size: 25, detail: "full" });
|
|
14730
14745
|
const stories = response?.data?.data;
|
|
14731
14746
|
const total = response?.data?.total;
|
|
14732
14747
|
if (!stories)
|
|
@@ -14734,7 +14749,7 @@ class ShortcutClientWrapper {
|
|
|
14734
14749
|
return { stories, total };
|
|
14735
14750
|
}
|
|
14736
14751
|
async searchIterations(query) {
|
|
14737
|
-
const response = await this.client.searchIterations({ query, page_size: 25, detail: "
|
|
14752
|
+
const response = await this.client.searchIterations({ query, page_size: 25, detail: "full" });
|
|
14738
14753
|
const iterations = response?.data?.data;
|
|
14739
14754
|
const total = response?.data?.total;
|
|
14740
14755
|
if (!iterations)
|
|
@@ -14742,7 +14757,7 @@ class ShortcutClientWrapper {
|
|
|
14742
14757
|
return { iterations, total };
|
|
14743
14758
|
}
|
|
14744
14759
|
async searchEpics(query) {
|
|
14745
|
-
const response = await this.client.searchEpics({ query, page_size: 25, detail: "
|
|
14760
|
+
const response = await this.client.searchEpics({ query, page_size: 25, detail: "full" });
|
|
14746
14761
|
const epics = response?.data?.data;
|
|
14747
14762
|
const total = response?.data?.total;
|
|
14748
14763
|
if (!epics)
|
|
@@ -14750,7 +14765,7 @@ class ShortcutClientWrapper {
|
|
|
14750
14765
|
return { epics, total };
|
|
14751
14766
|
}
|
|
14752
14767
|
async searchMilestones(query) {
|
|
14753
|
-
const response = await this.client.searchMilestones({ query, page_size: 25, detail: "
|
|
14768
|
+
const response = await this.client.searchMilestones({ query, page_size: 25, detail: "full" });
|
|
14754
14769
|
const milestones = response?.data?.data;
|
|
14755
14770
|
const total = response?.data?.total;
|
|
14756
14771
|
if (!milestones)
|
|
@@ -21563,7 +21578,7 @@ var import_client = __toESM(require_lib(), 1);
|
|
|
21563
21578
|
|
|
21564
21579
|
// package.json
|
|
21565
21580
|
var name = "@shortcut/mcp";
|
|
21566
|
-
var version = "0.
|
|
21581
|
+
var version = "0.7.0";
|
|
21567
21582
|
|
|
21568
21583
|
// src/tools/base.ts
|
|
21569
21584
|
class BaseTools {
|
|
@@ -21571,143 +21586,113 @@ class BaseTools {
|
|
|
21571
21586
|
constructor(client) {
|
|
21572
21587
|
this.client = client;
|
|
21573
21588
|
}
|
|
21574
|
-
|
|
21575
|
-
|
|
21589
|
+
async correctMember(entity) {
|
|
21590
|
+
if (!entity)
|
|
21591
|
+
return null;
|
|
21592
|
+
const {
|
|
21593
|
+
id,
|
|
21594
|
+
disabled,
|
|
21595
|
+
role,
|
|
21596
|
+
profile: { name: name2, email_address, mention_name }
|
|
21597
|
+
} = entity;
|
|
21598
|
+
return { id, name: name2, email_address, mention_name, role, disabled };
|
|
21599
|
+
}
|
|
21600
|
+
async correctWorkflow(entity) {
|
|
21601
|
+
if (!entity)
|
|
21602
|
+
return null;
|
|
21603
|
+
const { team_id, ...withoutTeam } = entity;
|
|
21604
|
+
return { ...withoutTeam };
|
|
21576
21605
|
}
|
|
21577
|
-
|
|
21606
|
+
async correctTeam(entity) {
|
|
21607
|
+
if (!entity)
|
|
21608
|
+
return null;
|
|
21609
|
+
const { member_ids, workflow_ids, ...withoutIds } = entity;
|
|
21610
|
+
const users = await this.client.getUserMap(member_ids);
|
|
21611
|
+
const workflows = await this.client.getWorkflowMap(workflow_ids);
|
|
21612
|
+
const correctedEntity = {
|
|
21613
|
+
...withoutIds,
|
|
21614
|
+
members: await Promise.all(member_ids.map((id) => this.correctMember(users.get(id))).filter(Boolean)),
|
|
21615
|
+
workflows: await Promise.all(workflow_ids.map((id) => this.correctWorkflow(workflows.get(id))).filter(Boolean))
|
|
21616
|
+
};
|
|
21617
|
+
return correctedEntity;
|
|
21618
|
+
}
|
|
21619
|
+
async correctIteration(entity) {
|
|
21620
|
+
if (!entity)
|
|
21621
|
+
return null;
|
|
21622
|
+
const { group_ids, ...withoutGroupIds } = entity;
|
|
21623
|
+
const teams = await this.client.getTeamMap(group_ids?.filter(Boolean));
|
|
21624
|
+
const correctedEntity = {
|
|
21625
|
+
...withoutGroupIds,
|
|
21626
|
+
teams: await Promise.all(group_ids?.map((id) => this.correctTeam(teams.get(id)))?.filter(Boolean) ?? [])
|
|
21627
|
+
};
|
|
21628
|
+
return correctedEntity;
|
|
21629
|
+
}
|
|
21630
|
+
async correctMilestone(entity) {
|
|
21631
|
+
return entity;
|
|
21632
|
+
}
|
|
21633
|
+
async correctEpic(entity) {
|
|
21634
|
+
const { group_id, owner_ids, requested_by_id, follower_ids, ...withoutIds } = entity;
|
|
21635
|
+
const users = await this.client.getUserMap([
|
|
21636
|
+
...new Set([...owner_ids, requested_by_id, ...follower_ids])
|
|
21637
|
+
]);
|
|
21638
|
+
const teams = await this.client.getTeamMap(group_id ? [group_id] : []);
|
|
21639
|
+
const correctedEntity = {
|
|
21640
|
+
...withoutIds,
|
|
21641
|
+
owners: (await Promise.all(owner_ids?.map((id) => this.correctMember(users.get(id))))).filter(Boolean) ?? [],
|
|
21642
|
+
requested_by: requested_by_id ? await this.correctMember(users.get(requested_by_id)) : null,
|
|
21643
|
+
followers: (await Promise.all(follower_ids?.map((id) => this.correctMember(users.get(id))))).filter(Boolean) ?? [],
|
|
21644
|
+
team: group_id ? await this.correctTeam(teams.get(group_id)) : null
|
|
21645
|
+
};
|
|
21646
|
+
return correctedEntity;
|
|
21647
|
+
}
|
|
21648
|
+
async correctStory(entity) {
|
|
21649
|
+
const { group_id, owner_ids, requested_by_id, follower_ids, workflow_id, ...withoutIds } = entity;
|
|
21650
|
+
const users = await this.client.getUserMap([
|
|
21651
|
+
...new Set([...owner_ids, requested_by_id, ...follower_ids])
|
|
21652
|
+
]);
|
|
21653
|
+
const teams = await this.client.getTeamMap(group_id ? [group_id] : []);
|
|
21654
|
+
const workflows = await this.client.getWorkflowMap(workflow_id ? [workflow_id] : []);
|
|
21655
|
+
const correctedEntity = {
|
|
21656
|
+
...withoutIds,
|
|
21657
|
+
owners: (await Promise.all(owner_ids?.map((id) => this.correctMember(users.get(id)))))?.filter(Boolean) ?? [],
|
|
21658
|
+
requested_by: requested_by_id ? await this.correctMember(users.get(requested_by_id)) : null,
|
|
21659
|
+
followers: (await Promise.all(follower_ids?.map((id) => this.correctMember(users.get(id)))))?.filter(Boolean) ?? [],
|
|
21660
|
+
team: group_id ? await this.correctTeam(teams.get(group_id)) : null,
|
|
21661
|
+
workflow: workflow_id ? await this.correctWorkflow(workflows.get(workflow_id)) : null
|
|
21662
|
+
};
|
|
21663
|
+
return correctedEntity;
|
|
21664
|
+
}
|
|
21665
|
+
async toCorrectedEntity(entity) {
|
|
21666
|
+
if (entity.entity_type === "workflow")
|
|
21667
|
+
return this.correctWorkflow(entity);
|
|
21668
|
+
if (entity.entity_type === "group")
|
|
21669
|
+
return this.correctTeam(entity);
|
|
21670
|
+
if (entity.entity_type === "iteration")
|
|
21671
|
+
return this.correctIteration(entity);
|
|
21672
|
+
if (entity.entity_type === "milestone")
|
|
21673
|
+
return this.correctMilestone(entity);
|
|
21674
|
+
if (entity.entity_type === "epic")
|
|
21675
|
+
return this.correctEpic(entity);
|
|
21676
|
+
if (entity.entity_type === "story")
|
|
21677
|
+
return this.correctStory(entity);
|
|
21678
|
+
return entity;
|
|
21679
|
+
}
|
|
21680
|
+
async toCorrectedEntities(entities) {
|
|
21681
|
+
return Promise.all(entities.map((entity) => this.toCorrectedEntity(entity)));
|
|
21682
|
+
}
|
|
21683
|
+
toResult(message, data) {
|
|
21684
|
+
return {
|
|
21685
|
+
content: [
|
|
21686
|
+
{
|
|
21687
|
+
type: "text",
|
|
21688
|
+
text: `${message}${data !== undefined ? `
|
|
21578
21689
|
|
|
21579
|
-
|
|
21580
|
-
|
|
21581
|
-
|
|
21582
|
-
|
|
21583
|
-
return "";
|
|
21584
|
-
if (Array.isArray(data))
|
|
21585
|
-
return formatArray(data, { ...options, indent });
|
|
21586
|
-
if (typeof data === "object")
|
|
21587
|
-
return formatObject(data, { ...options, indent });
|
|
21588
|
-
return formatPrimitive(data);
|
|
21589
|
-
}
|
|
21590
|
-
function formatPrimitive(value) {
|
|
21591
|
-
if (typeof value === "boolean")
|
|
21592
|
-
return value ? "Yes" : "No";
|
|
21593
|
-
return String(value);
|
|
21594
|
-
}
|
|
21595
|
-
function formatArray(arr, options = {}) {
|
|
21596
|
-
if (arr.length === 0)
|
|
21597
|
-
return "(empty)";
|
|
21598
|
-
const indent = options.indent || "";
|
|
21599
|
-
const nextIndent = `${indent} `;
|
|
21600
|
-
return arr.map((item) => {
|
|
21601
|
-
let formattedItem;
|
|
21602
|
-
if (typeof item === "object" && item !== null) {
|
|
21603
|
-
formattedItem = jsonToText(item, {
|
|
21604
|
-
...options,
|
|
21605
|
-
indent: nextIndent,
|
|
21606
|
-
depth: options.depth !== undefined ? options.depth - 1 : undefined
|
|
21607
|
-
});
|
|
21608
|
-
if (formattedItem.includes(`
|
|
21609
|
-
`))
|
|
21610
|
-
return `${indent}-
|
|
21611
|
-
${formattedItem}`;
|
|
21612
|
-
} else
|
|
21613
|
-
formattedItem = formatPrimitive(item);
|
|
21614
|
-
return `${indent}- ${formattedItem}`;
|
|
21615
|
-
}).join(`
|
|
21616
|
-
`);
|
|
21617
|
-
}
|
|
21618
|
-
function formatObject(obj, options = {}) {
|
|
21619
|
-
const indent = options.indent || "";
|
|
21620
|
-
const nextIndent = `${indent} `;
|
|
21621
|
-
if (options.depth !== undefined && options.depth <= 0)
|
|
21622
|
-
return `${indent}[Object]`;
|
|
21623
|
-
if (Object.keys(obj).length === 0)
|
|
21624
|
-
return `${indent}(empty)`;
|
|
21625
|
-
let keys;
|
|
21626
|
-
if (!options.include) {
|
|
21627
|
-
keys = Object.keys(obj);
|
|
21628
|
-
} else if (Array.isArray(options.include)) {
|
|
21629
|
-
const arr = options.include;
|
|
21630
|
-
keys = Object.keys(obj).filter((key) => arr.includes(key));
|
|
21631
|
-
} else {
|
|
21632
|
-
keys = Object.keys(obj).filter((key) => {
|
|
21633
|
-
const include = options.include;
|
|
21634
|
-
return key in include;
|
|
21635
|
-
});
|
|
21690
|
+
${JSON.stringify(data, null, 2)}` : ""}`
|
|
21691
|
+
}
|
|
21692
|
+
]
|
|
21693
|
+
};
|
|
21636
21694
|
}
|
|
21637
|
-
return keys.map((key) => {
|
|
21638
|
-
const value = obj[key];
|
|
21639
|
-
const formattedKey = formatKey(key);
|
|
21640
|
-
let nestedInclude;
|
|
21641
|
-
if (options.include && !Array.isArray(options.include)) {
|
|
21642
|
-
const includeValue = options.include[key];
|
|
21643
|
-
if (includeValue === true)
|
|
21644
|
-
nestedInclude = undefined;
|
|
21645
|
-
else
|
|
21646
|
-
nestedInclude = includeValue;
|
|
21647
|
-
}
|
|
21648
|
-
const formattedValue = jsonToText(value, {
|
|
21649
|
-
...options,
|
|
21650
|
-
include: nestedInclude,
|
|
21651
|
-
indent: nextIndent,
|
|
21652
|
-
depth: options.depth !== undefined ? options.depth - 1 : undefined
|
|
21653
|
-
});
|
|
21654
|
-
if (!formattedValue.includes(`
|
|
21655
|
-
`)) {
|
|
21656
|
-
return `${indent}${formattedKey}: ${formattedValue}`;
|
|
21657
|
-
}
|
|
21658
|
-
return `${indent}${formattedKey}:
|
|
21659
|
-
${formattedValue}`;
|
|
21660
|
-
}).join(`
|
|
21661
|
-
`);
|
|
21662
|
-
}
|
|
21663
|
-
function formatKey(key) {
|
|
21664
|
-
return key.replace(/([A-Z])/g, " $1").replace(/_/g, " ").trim().split(" ").map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
|
|
21665
21695
|
}
|
|
21666
|
-
var formatAsUnorderedList = (items, label) => {
|
|
21667
|
-
return `${label ? `${label}:` : ""}${items?.length ? `${label ? `
|
|
21668
|
-
` : ""}${formatArray(items)}` : `${label ? " " : ""}(none)`}`;
|
|
21669
|
-
};
|
|
21670
|
-
var formatStoryList = (stories, users, label) => {
|
|
21671
|
-
return formatAsUnorderedList(stories.map((story) => `sc-${story.id}: ${story.name} (Type: ${story.story_type}, State: ${story.completed ? "Completed" : story.started ? "In Progress" : "Not Started"}, Team: ${story.group_id ? `${story.group_id}` : "(none)"}, Epic: ${story.epic_id ? `${story.epic_id}` : "(none)"}, Iteration: ${story.iteration_id ? `${story.iteration_id}` : "(none)"}, Owners: ${story.owner_ids.map((ownerId) => users.get(ownerId)).filter((owner) => owner !== null).map((owner) => `@${owner.profile.mention_name}`).join(", ") || "(none)"})`), label);
|
|
21672
|
-
};
|
|
21673
|
-
var formatMemberList = (ids, users, label = "Members") => {
|
|
21674
|
-
return formatAsUnorderedList((ids || []).map((id) => {
|
|
21675
|
-
const user = users.get(id);
|
|
21676
|
-
return user ? `id=${user.id} @${user.profile.mention_name}` : `id=${id} [Unknown]`;
|
|
21677
|
-
}), label);
|
|
21678
|
-
};
|
|
21679
|
-
var formatWorkflowList = (ids, workflows) => {
|
|
21680
|
-
return formatAsUnorderedList((ids || []).map((id) => workflows.get(id)).filter((workflow) => !!workflow).map((workflow) => {
|
|
21681
|
-
const defaultState = workflow.states.find((state) => state.id === workflow.default_state_id);
|
|
21682
|
-
return `id=${workflow.id} name=${workflow.name}. Default state: ${defaultState ? `id=${defaultState.id} name=${defaultState.name}` : "[Unknown]"}`;
|
|
21683
|
-
}), "Workflows");
|
|
21684
|
-
};
|
|
21685
|
-
var formatPullRequestList = (branches) => {
|
|
21686
|
-
return formatAsUnorderedList((branches || []).flatMap((branch) => branch.pull_requests || []).map((pr) => `Title: ${pr.title}, Merged: ${pr.merged ? "Yes" : "No"}, URL: ${pr.url}`), "Pull Requests");
|
|
21687
|
-
};
|
|
21688
|
-
var formatTaskList = (tasks) => {
|
|
21689
|
-
return formatAsUnorderedList((tasks || []).map((task) => `[${task.complete ? "X" : " "}] ${task.description}`), "Tasks");
|
|
21690
|
-
};
|
|
21691
|
-
var formatStats = (stats, showPoints) => {
|
|
21692
|
-
const { num_stories_backlog, num_stories_unstarted, num_stories_started, num_stories_done } = stats;
|
|
21693
|
-
const { num_points_backlog, num_points_unstarted, num_points_started, num_points_done } = stats;
|
|
21694
|
-
const totalCount = num_stories_backlog + num_stories_unstarted + num_stories_started + num_stories_done;
|
|
21695
|
-
const totalUnstarted = num_stories_backlog + num_stories_unstarted;
|
|
21696
|
-
const totalPoints = (num_points_backlog || 0) + (num_points_unstarted || 0) + (num_points_started || 0) + (num_points_done || 0);
|
|
21697
|
-
const totalUnstartedPoints = (num_points_backlog || 0) + (num_points_unstarted || 0);
|
|
21698
|
-
const statsString = `Stats:
|
|
21699
|
-
- Total stories: ${totalCount}${showPoints ? ` (${totalPoints} points)` : ""}
|
|
21700
|
-
- Unstarted stories: ${totalUnstarted}${showPoints ? ` (${totalUnstartedPoints} points)` : ""}
|
|
21701
|
-
- Stories in progress: ${num_stories_started}${showPoints ? ` (${num_points_started || 0} points)` : ""}
|
|
21702
|
-
- Completed stories: ${num_stories_done}${showPoints ? ` (${num_points_done || 0} points)` : ""}`;
|
|
21703
|
-
if (showPoints && stats.num_stories_unestimated)
|
|
21704
|
-
return `${statsString}
|
|
21705
|
-
- (${stats.num_stories_unestimated} of the stories are unestimated)`;
|
|
21706
|
-
return statsString;
|
|
21707
|
-
};
|
|
21708
|
-
var formatUsersList = (users) => {
|
|
21709
|
-
return formatAsUnorderedList(users.map((user) => `id=${user.id} ${user?.profile?.mention_name ? `@${user.profile.mention_name}` : ""} : ""}`));
|
|
21710
|
-
};
|
|
21711
21696
|
|
|
21712
21697
|
// src/tools/utils/search.ts
|
|
21713
21698
|
var keyRenames = { name: "title" };
|
|
@@ -21813,29 +21798,13 @@ class EpicTools extends BaseTools {
|
|
|
21813
21798
|
throw new Error(`Failed to search for epics matching your query: "${query}"`);
|
|
21814
21799
|
if (!epics.length)
|
|
21815
21800
|
return this.toResult(`Result: No epics found.`);
|
|
21816
|
-
return this.toResult(`Result (first ${epics.length} shown of ${total} total epics found)
|
|
21817
|
-
${formatAsUnorderedList(epics.map((epic) => `${epic.id}: ${epic.name}`))}`);
|
|
21801
|
+
return this.toResult(`Result (first ${epics.length} shown of ${total} total epics found):`, await this.toCorrectedEntities(epics));
|
|
21818
21802
|
}
|
|
21819
21803
|
async getEpic(epicPublicId) {
|
|
21820
21804
|
const epic = await this.client.getEpic(epicPublicId);
|
|
21821
21805
|
if (!epic)
|
|
21822
21806
|
throw new Error(`Failed to retrieve Shortcut epic with public ID: ${epicPublicId}`);
|
|
21823
|
-
|
|
21824
|
-
const showPoints = !!currentUser?.workspace2?.estimate_scale?.length;
|
|
21825
|
-
return this.toResult(`Epic: ${epicPublicId}
|
|
21826
|
-
URL: ${epic.app_url}
|
|
21827
|
-
Name: ${epic.name}
|
|
21828
|
-
Archived: ${epic.archived ? "Yes" : "No"}
|
|
21829
|
-
Completed: ${epic.completed ? "Yes" : "No"}
|
|
21830
|
-
Started: ${epic.started ? "Yes" : "No"}
|
|
21831
|
-
Due date: ${epic.deadline ? epic.deadline : "[Not set]"}
|
|
21832
|
-
Team: ${epic.group_id ? `${epic.group_id}` : "(none)"}
|
|
21833
|
-
Objective: ${epic.milestone_id ? `${epic.milestone_id}` : "(none)"}
|
|
21834
|
-
|
|
21835
|
-
${formatStats(epic.stats, showPoints)}
|
|
21836
|
-
|
|
21837
|
-
Description:
|
|
21838
|
-
${epic.description}`);
|
|
21807
|
+
return this.toResult(`Epic: ${epicPublicId}`, await this.toCorrectedEntity(epic));
|
|
21839
21808
|
}
|
|
21840
21809
|
async createEpic({
|
|
21841
21810
|
name: name2,
|
|
@@ -21885,9 +21854,7 @@ class IterationTools extends BaseTools {
|
|
|
21885
21854
|
const { stories } = await this.client.listIterationStories(iterationPublicId);
|
|
21886
21855
|
if (!stories)
|
|
21887
21856
|
throw new Error(`Failed to retrieve Shortcut stories in iteration with public ID: ${iterationPublicId}.`);
|
|
21888
|
-
|
|
21889
|
-
return this.toResult(`Result (${stories.length} stories found):
|
|
21890
|
-
${formatStoryList(stories, owners)}`);
|
|
21857
|
+
return this.toResult(`Result (${stories.length} stories found):`, this.toCorrectedEntities(stories));
|
|
21891
21858
|
}
|
|
21892
21859
|
async searchIterations(params) {
|
|
21893
21860
|
const currentUser = await this.client.getCurrentUser();
|
|
@@ -21897,28 +21864,13 @@ ${formatStoryList(stories, owners)}`);
|
|
|
21897
21864
|
throw new Error(`Failed to search for iterations matching your query: "${query}".`);
|
|
21898
21865
|
if (!iterations.length)
|
|
21899
21866
|
return this.toResult(`Result: No iterations found.`);
|
|
21900
|
-
return this.toResult(`Result (first ${iterations.length} shown of ${total} total iterations found)
|
|
21901
|
-
${formatAsUnorderedList(iterations.map((iteration) => `${iteration.id}: ${iteration.name} (Start date: ${iteration.start_date}, End date: ${iteration.end_date})`))}`);
|
|
21867
|
+
return this.toResult(`Result (first ${iterations.length} shown of ${total} total iterations found):`, await this.toCorrectedEntities(iterations));
|
|
21902
21868
|
}
|
|
21903
21869
|
async getIteration(iterationPublicId) {
|
|
21904
21870
|
const iteration = await this.client.getIteration(iterationPublicId);
|
|
21905
21871
|
if (!iteration)
|
|
21906
21872
|
throw new Error(`Failed to retrieve Shortcut iteration with public ID: ${iterationPublicId}.`);
|
|
21907
|
-
|
|
21908
|
-
const showPoints = !!currentUser?.workspace2?.estimate_scale?.length;
|
|
21909
|
-
return this.toResult(`Iteration: ${iterationPublicId}
|
|
21910
|
-
Url: ${iteration.app_url}
|
|
21911
|
-
Name: ${iteration.name}
|
|
21912
|
-
Start date: ${iteration.start_date}
|
|
21913
|
-
End date: ${iteration.end_date}
|
|
21914
|
-
Completed: ${iteration.status === "completed" ? "Yes" : "No"}
|
|
21915
|
-
Started: ${iteration.status === "started" ? "Yes" : "No"}
|
|
21916
|
-
Team: ${iteration.group_ids?.length ? `${iteration.group_ids.join(", ")}` : "(none)"}
|
|
21917
|
-
|
|
21918
|
-
${formatStats(iteration.stats, showPoints)}
|
|
21919
|
-
|
|
21920
|
-
Description:
|
|
21921
|
-
${iteration.description}`);
|
|
21873
|
+
return this.toResult(`Iteration: ${iterationPublicId}`, await this.toCorrectedEntity(iteration));
|
|
21922
21874
|
}
|
|
21923
21875
|
async createIteration({
|
|
21924
21876
|
name: name2,
|
|
@@ -21974,22 +21926,13 @@ class ObjectiveTools extends BaseTools {
|
|
|
21974
21926
|
throw new Error(`Failed to search for milestones matching your query: "${query}"`);
|
|
21975
21927
|
if (!milestones.length)
|
|
21976
21928
|
return this.toResult(`Result: No milestones found.`);
|
|
21977
|
-
return this.toResult(`Result (first ${milestones.length} shown of ${total} total milestones found)
|
|
21978
|
-
${formatAsUnorderedList(milestones.map((milestone) => `${milestone.id}: ${milestone.name}`))}`);
|
|
21929
|
+
return this.toResult(`Result (first ${milestones.length} shown of ${total} total milestones found):`, await this.toCorrectedEntities(milestones));
|
|
21979
21930
|
}
|
|
21980
21931
|
async getObjective(objectivePublicId) {
|
|
21981
21932
|
const objective = await this.client.getMilestone(objectivePublicId);
|
|
21982
21933
|
if (!objective)
|
|
21983
21934
|
throw new Error(`Failed to retrieve Shortcut objective with public ID: ${objectivePublicId}`);
|
|
21984
|
-
return this.toResult(`Objective: ${objectivePublicId}
|
|
21985
|
-
Url: ${objective.app_url}
|
|
21986
|
-
Name: ${objective.name}
|
|
21987
|
-
Archived: ${objective.archived ? "Yes" : "No"}
|
|
21988
|
-
Completed: ${objective.completed ? "Yes" : "No"}
|
|
21989
|
-
Started: ${objective.started ? "Yes" : "No"}
|
|
21990
|
-
|
|
21991
|
-
Description:
|
|
21992
|
-
${objective.description}`);
|
|
21935
|
+
return this.toResult(`Objective: ${objectivePublicId}`, await this.toCorrectedEntity(objective));
|
|
21993
21936
|
}
|
|
21994
21937
|
}
|
|
21995
21938
|
|
|
@@ -22195,51 +22138,13 @@ The story will be added to the default state for the workflow.
|
|
|
22195
22138
|
throw new Error(`Failed to search for stories matching your query: "${query}".`);
|
|
22196
22139
|
if (!stories.length)
|
|
22197
22140
|
return this.toResult(`Result: No stories found.`);
|
|
22198
|
-
|
|
22199
|
-
return this.toResult(`Result (first ${stories.length} shown of ${total} total stories found):
|
|
22200
|
-
${formatStoryList(stories, users)}`);
|
|
22141
|
+
return this.toResult(`Result (first ${stories.length} shown of ${total} total stories found):`, await this.toCorrectedEntities(stories));
|
|
22201
22142
|
}
|
|
22202
22143
|
async getStory(storyPublicId) {
|
|
22203
22144
|
const story = await this.client.getStory(storyPublicId);
|
|
22204
22145
|
if (!story)
|
|
22205
22146
|
throw new Error(`Failed to retrieve Shortcut story with public ID: ${storyPublicId}.`);
|
|
22206
|
-
|
|
22207
|
-
...story.owner_ids,
|
|
22208
|
-
...story.comments.flatMap((c) => c.author_id)
|
|
22209
|
-
]);
|
|
22210
|
-
const users = await this.client.getUserMap([...relatedUsers].filter((id) => !!id));
|
|
22211
|
-
return this.toResult(`Story: sc-${storyPublicId}
|
|
22212
|
-
URL: ${story.app_url}
|
|
22213
|
-
Name: ${story.name}
|
|
22214
|
-
Type: ${story.story_type}
|
|
22215
|
-
Archived: ${story.archived ? "Yes" : "No"}
|
|
22216
|
-
Completed: ${story.completed ? "Yes" : "No"}
|
|
22217
|
-
Started: ${story.started ? "Yes" : "No"}
|
|
22218
|
-
Blocked: ${story.blocked ? "Yes" : "No"}
|
|
22219
|
-
Blocking: ${story.blocker ? "Yes" : "No"}
|
|
22220
|
-
Due date: ${story.deadline ? story.deadline : "(none)"}
|
|
22221
|
-
Team: ${story.group_id ? `${story.group_id}` : "(none)"}
|
|
22222
|
-
${formatMemberList(story.owner_ids, users, "Owners")}
|
|
22223
|
-
Epic: ${story.epic_id ? `${story.epic_id}` : "(none)"}
|
|
22224
|
-
Iteration: ${story.iteration_id ? `${story.iteration_id}` : "(none)"}
|
|
22225
|
-
|
|
22226
|
-
Description:
|
|
22227
|
-
${story.description}
|
|
22228
|
-
|
|
22229
|
-
${formatAsUnorderedList(story.external_links, "External Links")}
|
|
22230
|
-
|
|
22231
|
-
${formatPullRequestList(story.branches)}
|
|
22232
|
-
|
|
22233
|
-
${formatTaskList(story.tasks)}
|
|
22234
|
-
|
|
22235
|
-
Comments:
|
|
22236
|
-
${(story.comments || []).map((comment) => {
|
|
22237
|
-
const mentionName = comment.author_id ? users.get(comment.author_id)?.profile?.mention_name : null;
|
|
22238
|
-
return `- From: ${mentionName ? `@${mentionName}` : `id=${comment.author_id}` || "[Unknown]"} on ${comment.created_at}.
|
|
22239
|
-
${comment.text || ""}`;
|
|
22240
|
-
}).join(`
|
|
22241
|
-
|
|
22242
|
-
`)}`);
|
|
22147
|
+
return this.toResult(`Story: sc-${storyPublicId}`, await this.toCorrectedEntity(story));
|
|
22243
22148
|
}
|
|
22244
22149
|
async createStoryComment({
|
|
22245
22150
|
storyPublicId,
|
|
@@ -22374,27 +22279,13 @@ class TeamTools extends BaseTools {
|
|
|
22374
22279
|
const team = await this.client.getTeam(teamPublicId);
|
|
22375
22280
|
if (!team)
|
|
22376
22281
|
return this.toResult(`Team with public ID: ${teamPublicId} not found.`);
|
|
22377
|
-
|
|
22378
|
-
return this.toResult(`Id: ${team.id}
|
|
22379
|
-
Name: ${team.name}
|
|
22380
|
-
Mention name: ${team.mention_name}
|
|
22381
|
-
Description: ${team.description}
|
|
22382
|
-
${formatMemberList(team.member_ids, users)}`);
|
|
22282
|
+
return this.toResult(`Team: ${team.id}`, await this.toCorrectedEntity(team));
|
|
22383
22283
|
}
|
|
22384
22284
|
async getTeams() {
|
|
22385
22285
|
const teams = await this.client.getTeams();
|
|
22386
22286
|
if (!teams.length)
|
|
22387
22287
|
return this.toResult(`No teams found.`);
|
|
22388
|
-
|
|
22389
|
-
return this.toResult(`Result (first ${teams.length} shown of ${teams.length} total teams found):
|
|
22390
|
-
|
|
22391
|
-
${teams.map((team) => `Id: ${team.id}
|
|
22392
|
-
Name: ${team.name}
|
|
22393
|
-
Description: ${team.description}
|
|
22394
|
-
Number of Members: ${team.member_ids.length}
|
|
22395
|
-
${formatWorkflowList(team.workflow_ids, workflows)}`).join(`
|
|
22396
|
-
|
|
22397
|
-
`)}`);
|
|
22288
|
+
return this.toResult(`Result (first ${teams.length} shown of ${teams.length} total teams found):`, await this.toCorrectedEntities(teams));
|
|
22398
22289
|
}
|
|
22399
22290
|
}
|
|
22400
22291
|
|
|
@@ -22410,14 +22301,11 @@ class UserTools extends BaseTools {
|
|
|
22410
22301
|
const user2 = await this.client.getCurrentUser();
|
|
22411
22302
|
if (!user2)
|
|
22412
22303
|
throw new Error("Failed to retrieve current user.");
|
|
22413
|
-
return this.toResult(`Current user
|
|
22414
|
-
Id: ${user2.id}
|
|
22415
|
-
Mention name: @${user2.mention_name}
|
|
22416
|
-
Full name: ${user2.name}`);
|
|
22304
|
+
return this.toResult(`Current user:`, user2);
|
|
22417
22305
|
}
|
|
22418
22306
|
async listMembers() {
|
|
22419
22307
|
const members = await this.client.listMembers();
|
|
22420
|
-
return this.toResult(`Found ${members.length} members
|
|
22308
|
+
return this.toResult(`Found ${members.length} members:`, members);
|
|
22421
22309
|
}
|
|
22422
22310
|
}
|
|
22423
22311
|
|
|
@@ -22433,24 +22321,13 @@ class WorkflowTools extends BaseTools {
|
|
|
22433
22321
|
const workflow = await this.client.getWorkflow(workflowPublicId);
|
|
22434
22322
|
if (!workflow)
|
|
22435
22323
|
return this.toResult(`Workflow with public ID: ${workflowPublicId} not found.`);
|
|
22436
|
-
return this.toResult(`
|
|
22437
|
-
Name: ${workflow.name}
|
|
22438
|
-
Description: ${workflow.description}
|
|
22439
|
-
States:
|
|
22440
|
-
${formatAsUnorderedList(workflow.states.map((state) => `id=${state.id} name=${state.name} (default: ${state.id === workflow.default_state_id ? "yes" : "no"}, type: ${state.type})`))}`);
|
|
22324
|
+
return this.toResult(`Workflow: ${workflow.id}`, await this.toCorrectedEntity(workflow));
|
|
22441
22325
|
}
|
|
22442
22326
|
async listWorkflows() {
|
|
22443
22327
|
const workflows = await this.client.getWorkflows();
|
|
22444
22328
|
if (!workflows.length)
|
|
22445
22329
|
return this.toResult(`No workflows found.`);
|
|
22446
|
-
return this.toResult(`Result (first ${workflows.length} shown of ${workflows.length} total workflows found)
|
|
22447
|
-
|
|
22448
|
-
${workflows.map((workflow) => `Id: ${workflow.id}
|
|
22449
|
-
Name: ${workflow.name}
|
|
22450
|
-
Description: ${workflow.description}
|
|
22451
|
-
Default State: ${workflow.states.find((state) => state.id === workflow.default_state_id)?.name || "[Unknown]"}`).join(`
|
|
22452
|
-
|
|
22453
|
-
`)}`);
|
|
22330
|
+
return this.toResult(`Result (first ${workflows.length} shown of ${workflows.length} total workflows found):`, await this.toCorrectedEntities(workflows));
|
|
22454
22331
|
}
|
|
22455
22332
|
}
|
|
22456
22333
|
|