@task-boards/mcp-server 0.20.0 → 0.25.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/README.md +28 -0
- package/build/cli.js +950 -213
- package/build/cli.js.map +4 -4
- package/package.json +3 -2
- package/skills/task-boards-agent-runs/SKILL.md +58 -0
- package/skills/task-boards-attention/SKILL.md +60 -0
- package/skills/task-boards-git-sync/SKILL.md +55 -0
- package/skills/task-boards-orchestrator/SKILL.md +69 -0
- package/skills/task-boards-setup/SKILL.md +69 -0
- package/skills/task-boards-work-items/SKILL.md +55 -0
package/build/cli.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { fileURLToPath as __tb_fileURLToPath } from "node:url";
|
|
3
|
+
import { dirname as __tb_dirname } from "node:path";
|
|
4
|
+
const __filename = __tb_fileURLToPath(import.meta.url);
|
|
5
|
+
const __dirname = __tb_dirname(__filename);
|
|
2
6
|
var __create = Object.create;
|
|
3
7
|
var __defProp = Object.defineProperty;
|
|
4
8
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -39,7 +43,10 @@ var require_agent_runs_api = __commonJS({
|
|
|
39
43
|
retryAgentRun: (id) => `${exports.AGENT_RUNS_PREFIX}/${id}/retry`,
|
|
40
44
|
acknowledgeAgentRun: (id) => `${exports.AGENT_RUNS_PREFIX}/${id}/acknowledge`,
|
|
41
45
|
setAgentRunAttention: (id) => `${exports.AGENT_RUNS_PREFIX}/${id}/attention`,
|
|
42
|
-
completeAgentRun: (id) => `${exports.AGENT_RUNS_PREFIX}/${id}/complete
|
|
46
|
+
completeAgentRun: (id) => `${exports.AGENT_RUNS_PREFIX}/${id}/complete`,
|
|
47
|
+
registerAgentRunProcess: (agentRunId) => `${exports.AGENT_RUNS_PREFIX}/${agentRunId}/process-registration`,
|
|
48
|
+
getAgentRunProcessRegistration: (agentRunId) => `${exports.AGENT_RUNS_PREFIX}/${agentRunId}/process-registration`,
|
|
49
|
+
unregisterAgentRunProcess: (agentRunId) => `${exports.AGENT_RUNS_PREFIX}/${agentRunId}/process-registration`
|
|
43
50
|
};
|
|
44
51
|
}
|
|
45
52
|
});
|
|
@@ -652,7 +659,8 @@ var require_work_items_api = __commonJS({
|
|
|
652
659
|
updateWorkItem: (id) => `${exports.WORK_ITEMS_PREFIX}/${id}`,
|
|
653
660
|
deleteWorkItem: (id) => `${exports.WORK_ITEMS_PREFIX}/${id}`,
|
|
654
661
|
getDeletePreview: (id) => `${exports.WORK_ITEMS_PREFIX}/${id}/delete-preview`,
|
|
655
|
-
moveWorkItem: (id) => `${exports.WORK_ITEMS_PREFIX}/${id}/move
|
|
662
|
+
moveWorkItem: (id) => `${exports.WORK_ITEMS_PREFIX}/${id}/move`,
|
|
663
|
+
stopWorkItemAgent: (workItemId) => `${exports.WORK_ITEMS_PREFIX}/${workItemId}/stop-agent`
|
|
656
664
|
};
|
|
657
665
|
}
|
|
658
666
|
});
|
|
@@ -825,13 +833,24 @@ var require_feedback_enum = __commonJS({
|
|
|
825
833
|
"../api/build/feedback/feedback.enum.js"(exports) {
|
|
826
834
|
"use strict";
|
|
827
835
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
828
|
-
exports.FEEDBACK_TYPE = void 0;
|
|
836
|
+
exports.FEEDBACK_PULSE_ACTIVE_VIEW_VALUES = exports.FEEDBACK_PULSE_ACTIVE_VIEW = exports.FEEDBACK_INTERFACE_MODE = exports.FEEDBACK_TYPE = void 0;
|
|
829
837
|
exports.FEEDBACK_TYPE = {
|
|
830
838
|
BUG: "BUG",
|
|
831
839
|
IMPROVEMENT: "IMPROVEMENT",
|
|
832
840
|
QUESTION: "QUESTION",
|
|
833
841
|
OTHER: "OTHER"
|
|
834
842
|
};
|
|
843
|
+
exports.FEEDBACK_INTERFACE_MODE = {
|
|
844
|
+
PULSE: "pulse",
|
|
845
|
+
LEGACY: "legacy"
|
|
846
|
+
};
|
|
847
|
+
exports.FEEDBACK_PULSE_ACTIVE_VIEW = {
|
|
848
|
+
LIST: "list",
|
|
849
|
+
BOARD: "board",
|
|
850
|
+
TIMELINE: "timeline",
|
|
851
|
+
AGENTS: "agents"
|
|
852
|
+
};
|
|
853
|
+
exports.FEEDBACK_PULSE_ACTIVE_VIEW_VALUES = Object.values(exports.FEEDBACK_PULSE_ACTIVE_VIEW);
|
|
835
854
|
}
|
|
836
855
|
});
|
|
837
856
|
|
|
@@ -897,7 +916,10 @@ var require_notifications_enum = __commonJS({
|
|
|
897
916
|
AGENT_IDE_ATTENTION: "AGENT_IDE_ATTENTION",
|
|
898
917
|
AGENT_NEEDS_CLARIFICATION: "AGENT_NEEDS_CLARIFICATION",
|
|
899
918
|
AGENT_RUN_FAILED: "AGENT_RUN_FAILED",
|
|
900
|
-
AGENT_QA_HAS_BUGS: "AGENT_QA_HAS_BUGS"
|
|
919
|
+
AGENT_QA_HAS_BUGS: "AGENT_QA_HAS_BUGS",
|
|
920
|
+
AGENT_BATCH_COMPLETED: "AGENT_BATCH_COMPLETED",
|
|
921
|
+
WORK_ITEM_COMMENT: "WORK_ITEM_COMMENT",
|
|
922
|
+
WORK_ITEM_STATUS_CHANGE: "WORK_ITEM_STATUS_CHANGE"
|
|
901
923
|
};
|
|
902
924
|
}
|
|
903
925
|
});
|
|
@@ -937,6 +959,74 @@ var require_notifications = __commonJS({
|
|
|
937
959
|
}
|
|
938
960
|
});
|
|
939
961
|
|
|
962
|
+
// ../api/build/activity-feed/activity-feed.api.js
|
|
963
|
+
var require_activity_feed_api = __commonJS({
|
|
964
|
+
"../api/build/activity-feed/activity-feed.api.js"(exports) {
|
|
965
|
+
"use strict";
|
|
966
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
967
|
+
exports.ACTIVITY_FEED_ROUTES = exports.ACTIVITY_FEED_PREFIX = void 0;
|
|
968
|
+
exports.ACTIVITY_FEED_PREFIX = "/activity-feed";
|
|
969
|
+
exports.ACTIVITY_FEED_ROUTES = {
|
|
970
|
+
listActivityFeed: () => exports.ACTIVITY_FEED_PREFIX,
|
|
971
|
+
getUnreadCount: () => `${exports.ACTIVITY_FEED_PREFIX}/unread-count`
|
|
972
|
+
};
|
|
973
|
+
}
|
|
974
|
+
});
|
|
975
|
+
|
|
976
|
+
// ../api/build/activity-feed/activity-feed.enum.js
|
|
977
|
+
var require_activity_feed_enum = __commonJS({
|
|
978
|
+
"../api/build/activity-feed/activity-feed.enum.js"(exports) {
|
|
979
|
+
"use strict";
|
|
980
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
981
|
+
exports.ACTIVITY_FEED_KIND_VALUES = exports.ACTIVITY_FEED_KIND = void 0;
|
|
982
|
+
exports.ACTIVITY_FEED_KIND = {
|
|
983
|
+
AGENT_IDE_ATTENTION: "AGENT_IDE_ATTENTION",
|
|
984
|
+
AGENT_NEEDS_CLARIFICATION: "AGENT_NEEDS_CLARIFICATION",
|
|
985
|
+
AGENT_RUN_FAILED: "AGENT_RUN_FAILED",
|
|
986
|
+
AGENT_QA_HAS_BUGS: "AGENT_QA_HAS_BUGS",
|
|
987
|
+
AGENT_BATCH_COMPLETED: "AGENT_BATCH_COMPLETED",
|
|
988
|
+
WORK_ITEM_COMMENT: "WORK_ITEM_COMMENT",
|
|
989
|
+
WORK_ITEM_STATUS_CHANGE: "WORK_ITEM_STATUS_CHANGE"
|
|
990
|
+
};
|
|
991
|
+
exports.ACTIVITY_FEED_KIND_VALUES = Object.values(exports.ACTIVITY_FEED_KIND);
|
|
992
|
+
}
|
|
993
|
+
});
|
|
994
|
+
|
|
995
|
+
// ../api/build/activity-feed/activity-feed.types.js
|
|
996
|
+
var require_activity_feed_types = __commonJS({
|
|
997
|
+
"../api/build/activity-feed/activity-feed.types.js"(exports) {
|
|
998
|
+
"use strict";
|
|
999
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1000
|
+
}
|
|
1001
|
+
});
|
|
1002
|
+
|
|
1003
|
+
// ../api/build/activity-feed/index.js
|
|
1004
|
+
var require_activity_feed = __commonJS({
|
|
1005
|
+
"../api/build/activity-feed/index.js"(exports) {
|
|
1006
|
+
"use strict";
|
|
1007
|
+
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
1008
|
+
if (k2 === void 0) k2 = k;
|
|
1009
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
1010
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
1011
|
+
desc = { enumerable: true, get: function() {
|
|
1012
|
+
return m[k];
|
|
1013
|
+
} };
|
|
1014
|
+
}
|
|
1015
|
+
Object.defineProperty(o, k2, desc);
|
|
1016
|
+
}) : (function(o, m, k, k2) {
|
|
1017
|
+
if (k2 === void 0) k2 = k;
|
|
1018
|
+
o[k2] = m[k];
|
|
1019
|
+
}));
|
|
1020
|
+
var __exportStar = exports && exports.__exportStar || function(m, exports2) {
|
|
1021
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p)) __createBinding(exports2, m, p);
|
|
1022
|
+
};
|
|
1023
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1024
|
+
__exportStar(require_activity_feed_api(), exports);
|
|
1025
|
+
__exportStar(require_activity_feed_enum(), exports);
|
|
1026
|
+
__exportStar(require_activity_feed_types(), exports);
|
|
1027
|
+
}
|
|
1028
|
+
});
|
|
1029
|
+
|
|
940
1030
|
// ../api/build/agent-runs/agent-runs.types.js
|
|
941
1031
|
var require_agent_runs_types = __commonJS({
|
|
942
1032
|
"../api/build/agent-runs/agent-runs.types.js"(exports) {
|
|
@@ -1002,6 +1092,7 @@ var require_build = __commonJS({
|
|
|
1002
1092
|
__exportStar(require_comments(), exports);
|
|
1003
1093
|
__exportStar(require_feedback(), exports);
|
|
1004
1094
|
__exportStar(require_notifications(), exports);
|
|
1095
|
+
__exportStar(require_activity_feed(), exports);
|
|
1005
1096
|
__exportStar(require_agent_runs_api(), exports);
|
|
1006
1097
|
__exportStar(require_agent_runs_types(), exports);
|
|
1007
1098
|
}
|
|
@@ -1504,7 +1595,8 @@ var require_members_api = __commonJS({
|
|
|
1504
1595
|
updateMemberRole: (projectId, memberId) => `/projects/${projectId}/members/${memberId}`,
|
|
1505
1596
|
removeMember: (projectId, memberId) => `/projects/${projectId}/members/${memberId}`,
|
|
1506
1597
|
listInvitations: (projectId) => `/projects/${projectId}/invitations`,
|
|
1507
|
-
revokeInvitation: (projectId, invitationId) => `/projects/${projectId}/invitations/${invitationId}
|
|
1598
|
+
revokeInvitation: (projectId, invitationId) => `/projects/${projectId}/invitations/${invitationId}`,
|
|
1599
|
+
ensureServiceMember: (projectId) => `/projects/${projectId}/members/ensure-service-member`
|
|
1508
1600
|
};
|
|
1509
1601
|
}
|
|
1510
1602
|
});
|
|
@@ -1522,7 +1614,7 @@ var require_invitations_enums = __commonJS({
|
|
|
1522
1614
|
"../shared/build/internal/members/invitations.enums.js"(exports) {
|
|
1523
1615
|
"use strict";
|
|
1524
1616
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1525
|
-
exports.INVITE_OUTCOME = exports.INVITATION_STATUS = void 0;
|
|
1617
|
+
exports.ENSURE_SERVICE_MEMBER_OUTCOME = exports.INVITE_OUTCOME = exports.INVITATION_STATUS = void 0;
|
|
1526
1618
|
exports.INVITATION_STATUS = {
|
|
1527
1619
|
PENDING: "PENDING",
|
|
1528
1620
|
ACCEPTED: "ACCEPTED",
|
|
@@ -1533,6 +1625,10 @@ var require_invitations_enums = __commonJS({
|
|
|
1533
1625
|
MEMBER_ADDED: "MEMBER_ADDED",
|
|
1534
1626
|
INVITATION_SENT: "INVITATION_SENT"
|
|
1535
1627
|
};
|
|
1628
|
+
exports.ENSURE_SERVICE_MEMBER_OUTCOME = {
|
|
1629
|
+
ADDED: "added",
|
|
1630
|
+
ALREADY_PRESENT: "already_present"
|
|
1631
|
+
};
|
|
1536
1632
|
}
|
|
1537
1633
|
});
|
|
1538
1634
|
|
|
@@ -1631,6 +1727,7 @@ var require_exception_codes = __commonJS({
|
|
|
1631
1727
|
CANNOT_DEMOTE_LAST_OWNER: "CANNOT_DEMOTE_LAST_OWNER",
|
|
1632
1728
|
CANNOT_MODIFY_SERVICE_USER: "CANNOT_MODIFY_SERVICE_USER",
|
|
1633
1729
|
CANNOT_REMOVE_SERVICE_USER: "CANNOT_REMOVE_SERVICE_USER",
|
|
1730
|
+
SERVICE_MEMBER_ENSURE_NOT_APPLICABLE: "SERVICE_MEMBER_ENSURE_NOT_APPLICABLE",
|
|
1634
1731
|
AGENT_RUN_NOT_COMPLETABLE: "AGENT_RUN_NOT_COMPLETABLE",
|
|
1635
1732
|
AGENT_RUN_INFLIGHT: "AGENT_RUN_INFLIGHT",
|
|
1636
1733
|
AGENT_RUN_NOT_RETRYABLE: "AGENT_RUN_NOT_RETRYABLE",
|
|
@@ -1703,7 +1800,8 @@ var require_exception_codes = __commonJS({
|
|
|
1703
1800
|
PAYMENTS_DISABLED: "PAYMENTS_DISABLED",
|
|
1704
1801
|
PAYMENTS_NOT_CONFIGURED: "PAYMENTS_NOT_CONFIGURED",
|
|
1705
1802
|
PAYMENTS_PROBE_FAILED: "PAYMENTS_PROBE_FAILED",
|
|
1706
|
-
SYSTEM_READ_ONLY: "SYSTEM_READ_ONLY"
|
|
1803
|
+
SYSTEM_READ_ONLY: "SYSTEM_READ_ONLY",
|
|
1804
|
+
ESTIMATION_REQUIRED_FOR_MOVE: "ESTIMATION_REQUIRED_FOR_MOVE"
|
|
1707
1805
|
};
|
|
1708
1806
|
}
|
|
1709
1807
|
});
|
|
@@ -2275,6 +2373,7 @@ var require_realtime_events = __commonJS({
|
|
|
2275
2373
|
WORK_ITEM_UPDATED: "work_item.updated",
|
|
2276
2374
|
WORK_ITEM_MOVED: "work_item.moved",
|
|
2277
2375
|
AGENT_RUN_STATUS_CHANGED: "agent_run.status_changed",
|
|
2376
|
+
AGENT_ACTIVITY: "agent.activity",
|
|
2278
2377
|
COMMENT_CREATED: "comment.created",
|
|
2279
2378
|
COMMENT_DELETED: "comment.deleted",
|
|
2280
2379
|
WORK_ITEM_DELETED: "work_item.deleted",
|
|
@@ -2502,6 +2601,8 @@ var require_agentic_sdlc_phase_chain = __commonJS({
|
|
|
2502
2601
|
exports.advanceAnalysisPhaseSkippingUnbound = advanceAnalysisPhaseSkippingUnbound;
|
|
2503
2602
|
exports.initPendingDevRoles = initPendingDevRoles;
|
|
2504
2603
|
exports.removeDevRoleFromPending = removeDevRoleFromPending;
|
|
2604
|
+
exports.isArchitectCompletionHandoff = isArchitectCompletionHandoff;
|
|
2605
|
+
exports.resolvePostArchitectColumnWhenNoDevRoles = resolvePostArchitectColumnWhenNoDevRoles;
|
|
2505
2606
|
var subagent_role_enum_1 = require_subagent_role_enum();
|
|
2506
2607
|
var workflow_phase_enum_1 = require_workflow_phase_enum();
|
|
2507
2608
|
var subagent_role_util_1 = require_subagent_role_util();
|
|
@@ -2553,6 +2654,15 @@ var require_agentic_sdlc_phase_chain = __commonJS({
|
|
|
2553
2654
|
function removeDevRoleFromPending(pendingDevRoles, completedRole) {
|
|
2554
2655
|
return pendingDevRoles.filter((role) => role !== completedRole);
|
|
2555
2656
|
}
|
|
2657
|
+
function isArchitectCompletionHandoff(completedAgentRole, transition) {
|
|
2658
|
+
return completedAgentRole === subagent_role_enum_1.SUBAGENT_ROLE.ARCHITECT && transition.nextColumnSlug === "in-development" && transition.nextWorkflowPhase === null && (transition.kind === "MOVE" || transition.kind === "HANDOFF");
|
|
2659
|
+
}
|
|
2660
|
+
function resolvePostArchitectColumnWhenNoDevRoles(bindings) {
|
|
2661
|
+
if (isRoleBound(bindings, subagent_role_enum_1.SUBAGENT_ROLE.QA)) {
|
|
2662
|
+
return "in-qa";
|
|
2663
|
+
}
|
|
2664
|
+
return "done";
|
|
2665
|
+
}
|
|
2556
2666
|
}
|
|
2557
2667
|
});
|
|
2558
2668
|
|
|
@@ -2561,7 +2671,7 @@ var require_agentic_sdlc_workflow = __commonJS({
|
|
|
2561
2671
|
"../shared/build/workflows/agentic-sdlc.workflow.js"(exports) {
|
|
2562
2672
|
"use strict";
|
|
2563
2673
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2564
|
-
exports.removeDevRoleFromPending = exports.isRoleBound = exports.initPendingDevRoles = exports.getNextAnalysisPhase = exports.getFirstConfiguredAnalysisPhase = exports.advanceAnalysisPhaseSkippingUnbound = exports.IN_ANALYSIS_PHASE_CHAIN = exports.DEVELOPMENT_DEV_ROLES = exports.AGENTIC_SDLC_COLUMN_CLAIM_PRIORITY = exports.workflowPhaseToSubagentRole = exports.workflowPhaseToAgentRole = exports.subagentRoleToWorkflowPhase = exports.agentRoleToWorkflowPhase = exports.WORKFLOW_TRANSITION_KIND = exports.AGENTIC_SDLC_WORKFLOW = exports.AGENTIC_SDLC_AGENT_COLUMN_SLUGS = exports.IN_AWAITING_COLUMN_SLUG = void 0;
|
|
2674
|
+
exports.resolvePostArchitectColumnWhenNoDevRoles = exports.removeDevRoleFromPending = exports.isRoleBound = exports.isArchitectCompletionHandoff = exports.initPendingDevRoles = exports.getNextAnalysisPhase = exports.getFirstConfiguredAnalysisPhase = exports.advanceAnalysisPhaseSkippingUnbound = exports.IN_ANALYSIS_PHASE_CHAIN = exports.DEVELOPMENT_DEV_ROLES = exports.AGENTIC_SDLC_COLUMN_CLAIM_PRIORITY = exports.workflowPhaseToSubagentRole = exports.workflowPhaseToAgentRole = exports.subagentRoleToWorkflowPhase = exports.agentRoleToWorkflowPhase = exports.WORKFLOW_TRANSITION_KIND = exports.AGENTIC_SDLC_WORKFLOW = exports.AGENTIC_SDLC_AGENT_COLUMN_SLUGS = exports.IN_AWAITING_COLUMN_SLUG = void 0;
|
|
2565
2675
|
exports.isAgenticSdlcAgentColumnSlug = isAgenticSdlcAgentColumnSlug;
|
|
2566
2676
|
exports.isInAnalysisPhaseColumn = isInAnalysisPhaseColumn;
|
|
2567
2677
|
exports.resolveAgenticSdlcTransition = resolveAgenticSdlcTransition;
|
|
@@ -2798,12 +2908,18 @@ var require_agentic_sdlc_workflow = __commonJS({
|
|
|
2798
2908
|
Object.defineProperty(exports, "initPendingDevRoles", { enumerable: true, get: function() {
|
|
2799
2909
|
return agentic_sdlc_phase_chain_2.initPendingDevRoles;
|
|
2800
2910
|
} });
|
|
2911
|
+
Object.defineProperty(exports, "isArchitectCompletionHandoff", { enumerable: true, get: function() {
|
|
2912
|
+
return agentic_sdlc_phase_chain_2.isArchitectCompletionHandoff;
|
|
2913
|
+
} });
|
|
2801
2914
|
Object.defineProperty(exports, "isRoleBound", { enumerable: true, get: function() {
|
|
2802
2915
|
return agentic_sdlc_phase_chain_2.isRoleBound;
|
|
2803
2916
|
} });
|
|
2804
2917
|
Object.defineProperty(exports, "removeDevRoleFromPending", { enumerable: true, get: function() {
|
|
2805
2918
|
return agentic_sdlc_phase_chain_2.removeDevRoleFromPending;
|
|
2806
2919
|
} });
|
|
2920
|
+
Object.defineProperty(exports, "resolvePostArchitectColumnWhenNoDevRoles", { enumerable: true, get: function() {
|
|
2921
|
+
return agentic_sdlc_phase_chain_2.resolvePostArchitectColumnWhenNoDevRoles;
|
|
2922
|
+
} });
|
|
2807
2923
|
}
|
|
2808
2924
|
});
|
|
2809
2925
|
|
|
@@ -2926,7 +3042,7 @@ var require_workflows = __commonJS({
|
|
|
2926
3042
|
"../shared/build/workflows/index.js"(exports) {
|
|
2927
3043
|
"use strict";
|
|
2928
3044
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2929
|
-
exports.workflowPhaseToSubagentRole = exports.workflowPhaseToAgentRole = exports.subagentRoleToWorkflowPhase = exports.resolveAgenticSdlcTransition = exports.resolveAgenticSdlcNextColumnSlug = exports.removeDevRoleFromPending = exports.isRoleBound = exports.isInAnalysisPhaseColumn = exports.isAgenticSdlcAgentColumnSlug = exports.initPendingDevRoles = exports.getNextAnalysisPhase = exports.getFirstConfiguredAnalysisPhase = exports.agentRoleToWorkflowPhase = exports.advanceAnalysisPhaseSkippingUnbound = exports.WORKFLOW_TRANSITION_KIND = exports.IN_AWAITING_COLUMN_SLUG = exports.IN_ANALYSIS_PHASE_CHAIN = exports.DEVELOPMENT_DEV_ROLES = exports.AGENTIC_SDLC_WORKFLOW = exports.AGENTIC_SDLC_COLUMN_CLAIM_PRIORITY = exports.AGENTIC_SDLC_AGENT_COLUMN_SLUGS = exports.toPhysicalColumnSlug = exports.toLogicalColumnSlug = exports.shouldSyntheticEnqueue = exports.resolveLogicalColumnSlugForWorkItem = exports.isLogicalAgentColumnSlug = void 0;
|
|
3045
|
+
exports.workflowPhaseToSubagentRole = exports.workflowPhaseToAgentRole = exports.subagentRoleToWorkflowPhase = exports.resolvePostArchitectColumnWhenNoDevRoles = exports.resolveAgenticSdlcTransition = exports.resolveAgenticSdlcNextColumnSlug = exports.removeDevRoleFromPending = exports.isRoleBound = exports.isInAnalysisPhaseColumn = exports.isAgenticSdlcAgentColumnSlug = exports.isArchitectCompletionHandoff = exports.initPendingDevRoles = exports.getNextAnalysisPhase = exports.getFirstConfiguredAnalysisPhase = exports.agentRoleToWorkflowPhase = exports.advanceAnalysisPhaseSkippingUnbound = exports.WORKFLOW_TRANSITION_KIND = exports.IN_AWAITING_COLUMN_SLUG = exports.IN_ANALYSIS_PHASE_CHAIN = exports.DEVELOPMENT_DEV_ROLES = exports.AGENTIC_SDLC_WORKFLOW = exports.AGENTIC_SDLC_COLUMN_CLAIM_PRIORITY = exports.AGENTIC_SDLC_AGENT_COLUMN_SLUGS = exports.toPhysicalColumnSlug = exports.toLogicalColumnSlug = exports.shouldSyntheticEnqueue = exports.resolveLogicalColumnSlugForWorkItem = exports.isLogicalAgentColumnSlug = void 0;
|
|
2930
3046
|
var column_slug_mapping_1 = require_column_slug_mapping();
|
|
2931
3047
|
Object.defineProperty(exports, "isLogicalAgentColumnSlug", { enumerable: true, get: function() {
|
|
2932
3048
|
return column_slug_mapping_1.isLogicalAgentColumnSlug;
|
|
@@ -2980,6 +3096,9 @@ var require_workflows = __commonJS({
|
|
|
2980
3096
|
Object.defineProperty(exports, "initPendingDevRoles", { enumerable: true, get: function() {
|
|
2981
3097
|
return agentic_sdlc_workflow_1.initPendingDevRoles;
|
|
2982
3098
|
} });
|
|
3099
|
+
Object.defineProperty(exports, "isArchitectCompletionHandoff", { enumerable: true, get: function() {
|
|
3100
|
+
return agentic_sdlc_workflow_1.isArchitectCompletionHandoff;
|
|
3101
|
+
} });
|
|
2983
3102
|
Object.defineProperty(exports, "isAgenticSdlcAgentColumnSlug", { enumerable: true, get: function() {
|
|
2984
3103
|
return agentic_sdlc_workflow_1.isAgenticSdlcAgentColumnSlug;
|
|
2985
3104
|
} });
|
|
@@ -2998,6 +3117,9 @@ var require_workflows = __commonJS({
|
|
|
2998
3117
|
Object.defineProperty(exports, "resolveAgenticSdlcTransition", { enumerable: true, get: function() {
|
|
2999
3118
|
return agentic_sdlc_workflow_1.resolveAgenticSdlcTransition;
|
|
3000
3119
|
} });
|
|
3120
|
+
Object.defineProperty(exports, "resolvePostArchitectColumnWhenNoDevRoles", { enumerable: true, get: function() {
|
|
3121
|
+
return agentic_sdlc_workflow_1.resolvePostArchitectColumnWhenNoDevRoles;
|
|
3122
|
+
} });
|
|
3001
3123
|
Object.defineProperty(exports, "subagentRoleToWorkflowPhase", { enumerable: true, get: function() {
|
|
3002
3124
|
return agentic_sdlc_workflow_1.subagentRoleToWorkflowPhase;
|
|
3003
3125
|
} });
|
|
@@ -3291,10 +3413,18 @@ var require_slug_util = __commonJS({
|
|
|
3291
3413
|
"../shared/build/subagent/slug.util.js"(exports) {
|
|
3292
3414
|
"use strict";
|
|
3293
3415
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3416
|
+
exports.isValidSubagentSlugFormat = isValidSubagentSlugFormat;
|
|
3294
3417
|
exports.nameToSubagentSlug = nameToSubagentSlug;
|
|
3295
3418
|
exports.resolveSlugCollision = resolveSlugCollision;
|
|
3296
3419
|
var MAX_SUBAGENT_SLUG_LENGTH2 = 64;
|
|
3420
|
+
var SUBAGENT_SLUG_FORMAT_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
3297
3421
|
var FALLBACK_SLUG = "subagent";
|
|
3422
|
+
function isValidSubagentSlugFormat(slug) {
|
|
3423
|
+
if (slug.length === 0 || slug.length > MAX_SUBAGENT_SLUG_LENGTH2) {
|
|
3424
|
+
return false;
|
|
3425
|
+
}
|
|
3426
|
+
return SUBAGENT_SLUG_FORMAT_PATTERN.test(slug);
|
|
3427
|
+
}
|
|
3298
3428
|
function nameToSubagentSlug(name) {
|
|
3299
3429
|
const normalized = name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").replace(/-{2,}/g, "-");
|
|
3300
3430
|
if (normalized.length === 0) {
|
|
@@ -3397,7 +3527,7 @@ var require_subagent = __commonJS({
|
|
|
3397
3527
|
"../shared/build/subagent/index.js"(exports) {
|
|
3398
3528
|
"use strict";
|
|
3399
3529
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3400
|
-
exports.buildSubagentFileContentFromBody = exports.buildSubagentFileContent = exports.buildSubagentDefinition = exports.buildSubagentBodyMarkdown = exports.resolveSlugCollision = exports.nameToSubagentSlug = exports.SUBAGENT_PREVIEW_MODE = exports.validateSubagentLlmBodyMarkdown = exports.validateSubagentLlmInput = exports.BUILTIN_IDE_SUBAGENT_SLUGS = void 0;
|
|
3530
|
+
exports.buildSubagentFileContentFromBody = exports.buildSubagentFileContent = exports.buildSubagentDefinition = exports.buildSubagentBodyMarkdown = exports.resolveSlugCollision = exports.nameToSubagentSlug = exports.isValidSubagentSlugFormat = exports.SUBAGENT_PREVIEW_MODE = exports.validateSubagentLlmBodyMarkdown = exports.validateSubagentLlmInput = exports.BUILTIN_IDE_SUBAGENT_SLUGS = void 0;
|
|
3401
3531
|
var builtin_ide_subagents_const_1 = require_builtin_ide_subagents_const();
|
|
3402
3532
|
Object.defineProperty(exports, "BUILTIN_IDE_SUBAGENT_SLUGS", { enumerable: true, get: function() {
|
|
3403
3533
|
return builtin_ide_subagents_const_1.BUILTIN_IDE_SUBAGENT_SLUGS;
|
|
@@ -3415,6 +3545,9 @@ var require_subagent = __commonJS({
|
|
|
3415
3545
|
return subagent_preview_mode_enum_1.SUBAGENT_PREVIEW_MODE;
|
|
3416
3546
|
} });
|
|
3417
3547
|
var slug_util_1 = require_slug_util();
|
|
3548
|
+
Object.defineProperty(exports, "isValidSubagentSlugFormat", { enumerable: true, get: function() {
|
|
3549
|
+
return slug_util_1.isValidSubagentSlugFormat;
|
|
3550
|
+
} });
|
|
3418
3551
|
Object.defineProperty(exports, "nameToSubagentSlug", { enumerable: true, get: function() {
|
|
3419
3552
|
return slug_util_1.nameToSubagentSlug;
|
|
3420
3553
|
} });
|
|
@@ -3717,7 +3850,7 @@ var require_build2 = __commonJS({
|
|
|
3717
3850
|
});
|
|
3718
3851
|
|
|
3719
3852
|
// src/orchestrator/orchestrator-transport.ts
|
|
3720
|
-
var
|
|
3853
|
+
var import_agent_runs3 = __toESM(require_agent_runs_api(), 1);
|
|
3721
3854
|
var import_shared5 = __toESM(require_build2(), 1);
|
|
3722
3855
|
|
|
3723
3856
|
// src/tools/attachments.ts
|
|
@@ -3761,10 +3894,11 @@ var import_shared = __toESM(require_build2(), 1);
|
|
|
3761
3894
|
import axios, { isAxiosError } from "axios";
|
|
3762
3895
|
import FormData from "form-data";
|
|
3763
3896
|
var RestClientError = class extends Error {
|
|
3764
|
-
constructor(code, message, status) {
|
|
3897
|
+
constructor(code, message, status, details) {
|
|
3765
3898
|
super(message);
|
|
3766
3899
|
this.code = code;
|
|
3767
3900
|
this.status = status;
|
|
3901
|
+
this.details = details;
|
|
3768
3902
|
this.name = "RestClientError";
|
|
3769
3903
|
}
|
|
3770
3904
|
};
|
|
@@ -3824,7 +3958,7 @@ var RestClient = class {
|
|
|
3824
3958
|
if (isAxiosError(error)) {
|
|
3825
3959
|
const body = error.response?.data;
|
|
3826
3960
|
if (this.isApiErrorBody(body)) {
|
|
3827
|
-
throw new RestClientError(body.code, body.message, error.response?.status);
|
|
3961
|
+
throw new RestClientError(body.code, body.message, error.response?.status, body.details);
|
|
3828
3962
|
}
|
|
3829
3963
|
throw new RestClientError("HTTP_ERROR", this.sanitizeHttpErrorMessage(error.message), error.response?.status);
|
|
3830
3964
|
}
|
|
@@ -3840,7 +3974,7 @@ var RestClient = class {
|
|
|
3840
3974
|
if (isAxiosError(error)) {
|
|
3841
3975
|
const body = error.response?.data;
|
|
3842
3976
|
if (this.isApiErrorBody(body)) {
|
|
3843
|
-
throw new RestClientError(body.code, body.message, error.response?.status);
|
|
3977
|
+
throw new RestClientError(body.code, body.message, error.response?.status, body.details);
|
|
3844
3978
|
}
|
|
3845
3979
|
throw new RestClientError("HTTP_ERROR", this.sanitizeHttpErrorMessage(error.message), error.response?.status);
|
|
3846
3980
|
}
|
|
@@ -3987,21 +4121,75 @@ function shouldSanitizeResponses() {
|
|
|
3987
4121
|
return serverConfig.sanitizeResponses !== false;
|
|
3988
4122
|
}
|
|
3989
4123
|
|
|
3990
|
-
// src/tools/
|
|
3991
|
-
function
|
|
4124
|
+
// src/tools/agent-version-stale.util.ts
|
|
4125
|
+
function isRecord(value) {
|
|
4126
|
+
return typeof value === "object" && value !== null;
|
|
4127
|
+
}
|
|
4128
|
+
function isAgentVersionStaleErrorBody(value) {
|
|
4129
|
+
if (!isRecord(value)) {
|
|
4130
|
+
return false;
|
|
4131
|
+
}
|
|
4132
|
+
return typeof value.expectedVersion === "number" && typeof value.serverVersion === "number" && typeof value.serverUpdatedAt === "string";
|
|
4133
|
+
}
|
|
4134
|
+
function extractFieldConflictsFromAgentVersionStale(details) {
|
|
4135
|
+
if (details === void 0 || !isAgentVersionStaleErrorBody(details)) {
|
|
4136
|
+
return [];
|
|
4137
|
+
}
|
|
4138
|
+
const conflictingFields = details.diffSummary?.conflictingFields;
|
|
4139
|
+
if (!Array.isArray(conflictingFields)) {
|
|
4140
|
+
return [];
|
|
4141
|
+
}
|
|
4142
|
+
return conflictingFields.filter((field) => typeof field === "string");
|
|
4143
|
+
}
|
|
4144
|
+
|
|
4145
|
+
// src/tools/structured-tool-result.util.ts
|
|
4146
|
+
function buildSuccessStructuredResult(payload, textPayload) {
|
|
3992
4147
|
return {
|
|
3993
|
-
content: [{ type: "text", text: JSON.stringify(
|
|
4148
|
+
content: [{ type: "text", text: JSON.stringify(textPayload, null, 2) }],
|
|
4149
|
+
structuredContent: payload
|
|
3994
4150
|
};
|
|
3995
4151
|
}
|
|
3996
|
-
function
|
|
3997
|
-
const sanitizedMessage = shouldSanitizeResponses() ? (0, import_shared2.sanitizeMcpErrorMessage)(message) : message;
|
|
4152
|
+
function buildErrorStructuredResult(payload, textPayload) {
|
|
3998
4153
|
return {
|
|
3999
4154
|
isError: true,
|
|
4000
|
-
content: [{ type: "text", text: JSON.stringify(
|
|
4155
|
+
content: [{ type: "text", text: JSON.stringify(textPayload) }],
|
|
4156
|
+
structuredContent: payload
|
|
4157
|
+
};
|
|
4158
|
+
}
|
|
4159
|
+
function successStructuredPayload(data) {
|
|
4160
|
+
return { kind: "success", data };
|
|
4161
|
+
}
|
|
4162
|
+
function errorStructuredPayload(code, message, extras) {
|
|
4163
|
+
return {
|
|
4164
|
+
kind: "error",
|
|
4165
|
+
code,
|
|
4166
|
+
message,
|
|
4167
|
+
...extras?.fieldConflicts !== void 0 ? { fieldConflicts: extras.fieldConflicts } : {}
|
|
4001
4168
|
};
|
|
4002
4169
|
}
|
|
4170
|
+
|
|
4171
|
+
// src/tools/tool-utils.ts
|
|
4172
|
+
function jsonResult(data) {
|
|
4173
|
+
return buildSuccessStructuredResult(successStructuredPayload(data), data);
|
|
4174
|
+
}
|
|
4175
|
+
function toolError(code, message, extras) {
|
|
4176
|
+
const sanitizedMessage = shouldSanitizeResponses() ? (0, import_shared2.sanitizeMcpErrorMessage)(message) : message;
|
|
4177
|
+
const textPayload = { code, message: sanitizedMessage };
|
|
4178
|
+
if (extras?.fieldConflicts !== void 0) {
|
|
4179
|
+
textPayload.fieldConflicts = extras.fieldConflicts;
|
|
4180
|
+
}
|
|
4181
|
+
return buildErrorStructuredResult(errorStructuredPayload(code, sanitizedMessage, extras), textPayload);
|
|
4182
|
+
}
|
|
4003
4183
|
function toToolError(error) {
|
|
4004
|
-
if (error instanceof RestClientError
|
|
4184
|
+
if (error instanceof RestClientError) {
|
|
4185
|
+
if (error.code === "AGENT_VERSION_STALE") {
|
|
4186
|
+
return toolError(error.code, error.message, {
|
|
4187
|
+
fieldConflicts: extractFieldConflictsFromAgentVersionStale(error.details)
|
|
4188
|
+
});
|
|
4189
|
+
}
|
|
4190
|
+
return toolError(error.code, error.message);
|
|
4191
|
+
}
|
|
4192
|
+
if (error instanceof WorkspaceError) {
|
|
4005
4193
|
return toolError(error.code, error.message);
|
|
4006
4194
|
}
|
|
4007
4195
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
@@ -4246,145 +4434,11 @@ async function syncProjectSubagents(client, params) {
|
|
|
4246
4434
|
}
|
|
4247
4435
|
|
|
4248
4436
|
// src/tools/wait-for-agent-runs.ts
|
|
4249
|
-
var
|
|
4437
|
+
var import_agent_runs2 = __toESM(require_agent_runs_api(), 1);
|
|
4250
4438
|
var import_agent_run_status = __toESM(require_agent_run_status_enum(), 1);
|
|
4251
|
-
var DEFAULT_RETRY_BASE_MS = 500;
|
|
4252
|
-
var DEFAULT_RETRY_MAX_MS = 3e4;
|
|
4253
|
-
var DEFAULT_INFLIGHT_LIMIT = 10;
|
|
4254
|
-
function sleep(ms) {
|
|
4255
|
-
return new Promise((resolve4) => {
|
|
4256
|
-
setTimeout(resolve4, ms);
|
|
4257
|
-
});
|
|
4258
|
-
}
|
|
4259
|
-
function isTransientClaimError(error) {
|
|
4260
|
-
if (!(error instanceof RestClientError)) {
|
|
4261
|
-
return false;
|
|
4262
|
-
}
|
|
4263
|
-
if (error.status === void 0) {
|
|
4264
|
-
return error.code === "HTTP_ERROR";
|
|
4265
|
-
}
|
|
4266
|
-
return error.status >= 500;
|
|
4267
|
-
}
|
|
4268
|
-
function computeBackoffMs(consecutiveFailures, baseMs, maxMs) {
|
|
4269
|
-
const exponential = baseMs * 2 ** (consecutiveFailures - 1);
|
|
4270
|
-
return Math.min(exponential, maxMs);
|
|
4271
|
-
}
|
|
4272
|
-
function compareInflightRuns(a, b) {
|
|
4273
|
-
if (a.requiresAttention !== b.requiresAttention) {
|
|
4274
|
-
return a.requiresAttention ? -1 : 1;
|
|
4275
|
-
}
|
|
4276
|
-
const aDispatched = a.dispatchedAt ?? "";
|
|
4277
|
-
const bDispatched = b.dispatchedAt ?? "";
|
|
4278
|
-
return aDispatched.localeCompare(bDispatched);
|
|
4279
|
-
}
|
|
4280
|
-
async function fetchInflightAgentRuns(client, options) {
|
|
4281
|
-
const limit = options.limit ?? DEFAULT_INFLIGHT_LIMIT;
|
|
4282
|
-
const page = await client.get(import_agent_runs.AGENT_RUNS_ROUTES.listAgentRuns(), {
|
|
4283
|
-
projectId: options.projectId,
|
|
4284
|
-
activeOnly: "true",
|
|
4285
|
-
limit: String(limit)
|
|
4286
|
-
});
|
|
4287
|
-
const filtered = page.items.filter(
|
|
4288
|
-
(run) => run.status === import_agent_run_status.AGENT_RUN_STATUS.DISPATCHED || run.status === import_agent_run_status.AGENT_RUN_STATUS.ACKNOWLEDGED
|
|
4289
|
-
);
|
|
4290
|
-
filtered.sort(compareInflightRuns);
|
|
4291
|
-
return filtered.slice(0, limit);
|
|
4292
|
-
}
|
|
4293
|
-
async function pollAgentRuns(client, options, deps) {
|
|
4294
|
-
const { projectId, timeoutMs, pollIntervalMs, limit } = options;
|
|
4295
|
-
if (pollIntervalMs > timeoutMs) {
|
|
4296
|
-
throw new WorkspaceError("VALIDATION_ERROR", "pollInterval must not exceed timeout");
|
|
4297
|
-
}
|
|
4298
|
-
const sleepFn = deps?.sleep ?? sleep;
|
|
4299
|
-
const deadline = Date.now() + timeoutMs;
|
|
4300
|
-
const claimLimit = limit ?? 1;
|
|
4301
|
-
const retryBaseMs = options.retryBaseMs ?? DEFAULT_RETRY_BASE_MS;
|
|
4302
|
-
const retryMaxMs = options.retryMaxMs ?? DEFAULT_RETRY_MAX_MS;
|
|
4303
|
-
let consecutiveFailures = 0;
|
|
4304
|
-
while (true) {
|
|
4305
|
-
let response;
|
|
4306
|
-
try {
|
|
4307
|
-
response = await client.post(import_agent_runs.AGENT_RUNS_ROUTES.claimAgentRuns(), {
|
|
4308
|
-
projectId,
|
|
4309
|
-
limit: claimLimit
|
|
4310
|
-
});
|
|
4311
|
-
consecutiveFailures = 0;
|
|
4312
|
-
} catch (error) {
|
|
4313
|
-
if (!isTransientClaimError(error)) {
|
|
4314
|
-
throw error;
|
|
4315
|
-
}
|
|
4316
|
-
if (Date.now() >= deadline) {
|
|
4317
|
-
return { items: [], inflightRuns: [], timedOut: true };
|
|
4318
|
-
}
|
|
4319
|
-
consecutiveFailures += 1;
|
|
4320
|
-
const backoffMs = computeBackoffMs(consecutiveFailures, retryBaseMs, retryMaxMs);
|
|
4321
|
-
const remainingMs2 = deadline - Date.now();
|
|
4322
|
-
await sleepFn(Math.min(backoffMs, remainingMs2));
|
|
4323
|
-
continue;
|
|
4324
|
-
}
|
|
4325
|
-
if (response.items.length > 0) {
|
|
4326
|
-
return { items: response.items, inflightRuns: [], timedOut: false };
|
|
4327
|
-
}
|
|
4328
|
-
const inflightRuns = await fetchInflightAgentRuns(client, { projectId, limit: claimLimit });
|
|
4329
|
-
if (inflightRuns.length > 0) {
|
|
4330
|
-
return { items: [], inflightRuns, timedOut: false };
|
|
4331
|
-
}
|
|
4332
|
-
if (Date.now() >= deadline) {
|
|
4333
|
-
return { items: [], inflightRuns: [], timedOut: true };
|
|
4334
|
-
}
|
|
4335
|
-
const remainingMs = deadline - Date.now();
|
|
4336
|
-
const waitMs = Math.min(pollIntervalMs, remainingMs);
|
|
4337
|
-
await sleepFn(waitMs);
|
|
4338
|
-
}
|
|
4339
|
-
}
|
|
4340
4439
|
|
|
4341
|
-
// src/
|
|
4342
|
-
var
|
|
4343
|
-
constructor(client, options = {}) {
|
|
4344
|
-
this.client = client;
|
|
4345
|
-
this.options = options;
|
|
4346
|
-
}
|
|
4347
|
-
async claimAndPoll(options, deps) {
|
|
4348
|
-
return pollAgentRuns(this.client, options, deps);
|
|
4349
|
-
}
|
|
4350
|
-
async fetchInflightRuns(projectId, limit) {
|
|
4351
|
-
return fetchInflightAgentRuns(this.client, { projectId, limit });
|
|
4352
|
-
}
|
|
4353
|
-
async ackRun(agentRunId, note) {
|
|
4354
|
-
const body = note !== void 0 ? { note } : void 0;
|
|
4355
|
-
return this.client.patch(import_agent_runs2.AGENT_RUNS_ROUTES.acknowledgeAgentRun(agentRunId), body);
|
|
4356
|
-
}
|
|
4357
|
-
async setAttention(agentRunId, requiresAttention, message) {
|
|
4358
|
-
const body = requiresAttention ? { requiresAttention: true, attentionMessage: message ?? "" } : { requiresAttention: false };
|
|
4359
|
-
return this.client.patch(import_agent_runs2.AGENT_RUNS_ROUTES.setAgentRunAttention(agentRunId), body);
|
|
4360
|
-
}
|
|
4361
|
-
async completeRun(agentRunId, body) {
|
|
4362
|
-
return this.client.post(import_agent_runs2.AGENT_RUNS_ROUTES.completeAgentRun(agentRunId), body);
|
|
4363
|
-
}
|
|
4364
|
-
async listAttachments(workItemId) {
|
|
4365
|
-
return fetchAttachments(this.client, workItemId);
|
|
4366
|
-
}
|
|
4367
|
-
async downloadAttachments(workItemId, workspaceRoot, attachmentIds) {
|
|
4368
|
-
return downloadWorkItemAttachments(this.client, {
|
|
4369
|
-
workItemId,
|
|
4370
|
-
workspaceRoot,
|
|
4371
|
-
attachmentIds,
|
|
4372
|
-
blockSensitiveAttachments: this.options.blockSensitiveAttachments ?? true
|
|
4373
|
-
});
|
|
4374
|
-
}
|
|
4375
|
-
async syncSubagents(projectId, workspaceRoot) {
|
|
4376
|
-
return syncProjectSubagents(this.client, { projectId, workspaceRoot });
|
|
4377
|
-
}
|
|
4378
|
-
async createComment(workItemId, body) {
|
|
4379
|
-
return postComment(this.client, workItemId, body);
|
|
4380
|
-
}
|
|
4381
|
-
};
|
|
4382
|
-
function createOrchestratorTransport(client, config) {
|
|
4383
|
-
return new OrchestratorTransport(client, {
|
|
4384
|
-
workspaceRoot: config?.workspaceRoot,
|
|
4385
|
-
blockSensitiveAttachments: config?.blockSensitiveAttachments
|
|
4386
|
-
});
|
|
4387
|
-
}
|
|
4440
|
+
// src/agent-process/stop-signal.handler.ts
|
|
4441
|
+
var import_agent_runs = __toESM(require_agent_runs_api(), 1);
|
|
4388
4442
|
|
|
4389
4443
|
// src/orchestrator/active-run-state.ts
|
|
4390
4444
|
import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync2, rmSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
@@ -4393,7 +4447,7 @@ var ACTIVE_RUN_STATE_RELATIVE_PATH = ".cursor/orchestrator-active-run.json";
|
|
|
4393
4447
|
var ATTENTION_PENDING_RELATIVE_PATH = ".cursor/orchestrator-attention-pending.json";
|
|
4394
4448
|
var ACTIVE_RUN_LEASE_MINUTES = 30;
|
|
4395
4449
|
var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
4396
|
-
function
|
|
4450
|
+
function isRecord2(value) {
|
|
4397
4451
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4398
4452
|
}
|
|
4399
4453
|
function isUuid(value) {
|
|
@@ -4419,7 +4473,7 @@ function ensureCursorDir(workspaceRoot) {
|
|
|
4419
4473
|
}
|
|
4420
4474
|
}
|
|
4421
4475
|
function parseActiveRunState(raw) {
|
|
4422
|
-
if (!
|
|
4476
|
+
if (!isRecord2(raw)) {
|
|
4423
4477
|
return null;
|
|
4424
4478
|
}
|
|
4425
4479
|
const version = raw.version;
|
|
@@ -4441,7 +4495,7 @@ function parseActiveRunState(raw) {
|
|
|
4441
4495
|
};
|
|
4442
4496
|
}
|
|
4443
4497
|
function parseAttentionPendingState(raw) {
|
|
4444
|
-
if (!
|
|
4498
|
+
if (!isRecord2(raw)) {
|
|
4445
4499
|
return null;
|
|
4446
4500
|
}
|
|
4447
4501
|
const agentRunId = raw.agentRunId;
|
|
@@ -4528,30 +4582,272 @@ function clearOrchestratorBridgeState(workspaceRoot) {
|
|
|
4528
4582
|
clearAttentionPendingState(workspaceRoot);
|
|
4529
4583
|
}
|
|
4530
4584
|
|
|
4531
|
-
// src/
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4585
|
+
// src/agent-process/local-process-registry.ts
|
|
4586
|
+
var registrations = /* @__PURE__ */ new Map();
|
|
4587
|
+
function registerLocalProcess(agentRunId, workItemId, pid) {
|
|
4588
|
+
const entry = {
|
|
4589
|
+
agentRunId,
|
|
4590
|
+
workItemId,
|
|
4591
|
+
pid,
|
|
4592
|
+
registeredAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4593
|
+
};
|
|
4594
|
+
registrations.set(agentRunId, entry);
|
|
4595
|
+
return entry;
|
|
4596
|
+
}
|
|
4597
|
+
function getLocalProcess(agentRunId) {
|
|
4598
|
+
return registrations.get(agentRunId);
|
|
4599
|
+
}
|
|
4600
|
+
function unregisterLocalProcess(agentRunId) {
|
|
4601
|
+
registrations.delete(agentRunId);
|
|
4602
|
+
}
|
|
4603
|
+
|
|
4604
|
+
// src/agent-process/stop-signal.handler.ts
|
|
4605
|
+
var STOP_SIGTERM_GRACE_MS = 5e3;
|
|
4606
|
+
function defaultSleep(ms) {
|
|
4607
|
+
return new Promise((resolve4) => {
|
|
4608
|
+
setTimeout(resolve4, ms);
|
|
4609
|
+
});
|
|
4610
|
+
}
|
|
4611
|
+
function resolveWorkspaceRootForConfig(config) {
|
|
4612
|
+
try {
|
|
4613
|
+
return resolveWorkspaceRoot(void 0, config.workspaceRoot);
|
|
4614
|
+
} catch {
|
|
4548
4615
|
return null;
|
|
4549
4616
|
}
|
|
4550
|
-
return match[1] ?? null;
|
|
4551
4617
|
}
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4618
|
+
async function signalProcessGracefully(pid, deps) {
|
|
4619
|
+
const kill = deps.kill ?? process.kill.bind(process);
|
|
4620
|
+
const sleep2 = deps.sleep ?? defaultSleep;
|
|
4621
|
+
try {
|
|
4622
|
+
kill(pid, "SIGINT");
|
|
4623
|
+
} catch (error) {
|
|
4624
|
+
const code = error.code;
|
|
4625
|
+
if (code === "ESRCH") {
|
|
4626
|
+
return false;
|
|
4627
|
+
}
|
|
4628
|
+
deps.logWarn?.(`stop signal SIGINT failed for pid=${pid}: ${code ?? "unknown"}`);
|
|
4629
|
+
return false;
|
|
4630
|
+
}
|
|
4631
|
+
await sleep2(STOP_SIGTERM_GRACE_MS);
|
|
4632
|
+
try {
|
|
4633
|
+
kill(pid, "SIGTERM");
|
|
4634
|
+
} catch (error) {
|
|
4635
|
+
const code = error.code;
|
|
4636
|
+
if (code === "ESRCH") {
|
|
4637
|
+
return true;
|
|
4638
|
+
}
|
|
4639
|
+
deps.logWarn?.(`stop signal SIGTERM failed for pid=${pid}: ${code ?? "unknown"}`);
|
|
4640
|
+
}
|
|
4641
|
+
return true;
|
|
4642
|
+
}
|
|
4643
|
+
async function applyStopSignal(client, config, agentRunId, deps = {}) {
|
|
4644
|
+
let registration;
|
|
4645
|
+
try {
|
|
4646
|
+
registration = await client.get(
|
|
4647
|
+
import_agent_runs.AGENT_RUNS_ROUTES.getAgentRunProcessRegistration(agentRunId)
|
|
4648
|
+
);
|
|
4649
|
+
} catch {
|
|
4650
|
+
return false;
|
|
4651
|
+
}
|
|
4652
|
+
if (!registration.stopRequested) {
|
|
4653
|
+
return false;
|
|
4654
|
+
}
|
|
4655
|
+
const local = getLocalProcess(agentRunId);
|
|
4656
|
+
const pid = local?.pid ?? registration.pid;
|
|
4657
|
+
const signaled = await signalProcessGracefully(pid, deps);
|
|
4658
|
+
const workspaceRoot = resolveWorkspaceRootForConfig(config);
|
|
4659
|
+
if (workspaceRoot !== null) {
|
|
4660
|
+
const activeState = readActiveRunState(workspaceRoot);
|
|
4661
|
+
if (activeState?.agentRunId === agentRunId) {
|
|
4662
|
+
clearOrchestratorBridgeState(workspaceRoot);
|
|
4663
|
+
}
|
|
4664
|
+
}
|
|
4665
|
+
try {
|
|
4666
|
+
await client.delete(import_agent_runs.AGENT_RUNS_ROUTES.unregisterAgentRunProcess(agentRunId));
|
|
4667
|
+
} catch {
|
|
4668
|
+
deps.logWarn?.(`failed to unregister process registration for agentRunId=${agentRunId}`);
|
|
4669
|
+
}
|
|
4670
|
+
unregisterLocalProcess(agentRunId);
|
|
4671
|
+
return signaled;
|
|
4672
|
+
}
|
|
4673
|
+
async function pollActiveRunStopSignal(client, config, deps = {}) {
|
|
4674
|
+
const workspaceRoot = resolveWorkspaceRootForConfig(config);
|
|
4675
|
+
if (workspaceRoot === null) {
|
|
4676
|
+
return false;
|
|
4677
|
+
}
|
|
4678
|
+
const activeState = readActiveRunState(workspaceRoot);
|
|
4679
|
+
if (activeState === null) {
|
|
4680
|
+
return false;
|
|
4681
|
+
}
|
|
4682
|
+
return applyStopSignal(client, config, activeState.agentRunId, deps);
|
|
4683
|
+
}
|
|
4684
|
+
|
|
4685
|
+
// src/tools/wait-for-agent-runs.ts
|
|
4686
|
+
var DEFAULT_RETRY_BASE_MS = 500;
|
|
4687
|
+
var DEFAULT_RETRY_MAX_MS = 3e4;
|
|
4688
|
+
var DEFAULT_INFLIGHT_LIMIT = 10;
|
|
4689
|
+
function sleep(ms) {
|
|
4690
|
+
return new Promise((resolve4) => {
|
|
4691
|
+
setTimeout(resolve4, ms);
|
|
4692
|
+
});
|
|
4693
|
+
}
|
|
4694
|
+
function isTransientClaimError(error) {
|
|
4695
|
+
if (!(error instanceof RestClientError)) {
|
|
4696
|
+
return false;
|
|
4697
|
+
}
|
|
4698
|
+
if (error.status === void 0) {
|
|
4699
|
+
return error.code === "HTTP_ERROR";
|
|
4700
|
+
}
|
|
4701
|
+
return error.status >= 500;
|
|
4702
|
+
}
|
|
4703
|
+
function computeBackoffMs(consecutiveFailures, baseMs, maxMs) {
|
|
4704
|
+
const exponential = baseMs * 2 ** (consecutiveFailures - 1);
|
|
4705
|
+
return Math.min(exponential, maxMs);
|
|
4706
|
+
}
|
|
4707
|
+
function compareInflightRuns(a, b) {
|
|
4708
|
+
if (a.requiresAttention !== b.requiresAttention) {
|
|
4709
|
+
return a.requiresAttention ? -1 : 1;
|
|
4710
|
+
}
|
|
4711
|
+
const aDispatched = a.dispatchedAt ?? "";
|
|
4712
|
+
const bDispatched = b.dispatchedAt ?? "";
|
|
4713
|
+
return aDispatched.localeCompare(bDispatched);
|
|
4714
|
+
}
|
|
4715
|
+
async function fetchInflightAgentRuns(client, options) {
|
|
4716
|
+
const limit = options.limit ?? DEFAULT_INFLIGHT_LIMIT;
|
|
4717
|
+
const page = await client.get(import_agent_runs2.AGENT_RUNS_ROUTES.listAgentRuns(), {
|
|
4718
|
+
projectId: options.projectId,
|
|
4719
|
+
activeOnly: "true",
|
|
4720
|
+
limit: String(limit)
|
|
4721
|
+
});
|
|
4722
|
+
const filtered = page.items.filter(
|
|
4723
|
+
(run) => run.status === import_agent_run_status.AGENT_RUN_STATUS.DISPATCHED || run.status === import_agent_run_status.AGENT_RUN_STATUS.ACKNOWLEDGED
|
|
4724
|
+
);
|
|
4725
|
+
filtered.sort(compareInflightRuns);
|
|
4726
|
+
return filtered.slice(0, limit);
|
|
4727
|
+
}
|
|
4728
|
+
async function pollAgentRuns(client, options, deps) {
|
|
4729
|
+
const { projectId, timeoutMs, pollIntervalMs, limit } = options;
|
|
4730
|
+
if (pollIntervalMs > timeoutMs) {
|
|
4731
|
+
throw new WorkspaceError("VALIDATION_ERROR", "pollInterval must not exceed timeout");
|
|
4732
|
+
}
|
|
4733
|
+
const sleepFn = deps?.sleep ?? sleep;
|
|
4734
|
+
const deadline = Date.now() + timeoutMs;
|
|
4735
|
+
const claimLimit = limit ?? 1;
|
|
4736
|
+
const retryBaseMs = options.retryBaseMs ?? DEFAULT_RETRY_BASE_MS;
|
|
4737
|
+
const retryMaxMs = options.retryMaxMs ?? DEFAULT_RETRY_MAX_MS;
|
|
4738
|
+
let consecutiveFailures = 0;
|
|
4739
|
+
while (true) {
|
|
4740
|
+
if (options.stopSignal !== void 0) {
|
|
4741
|
+
await pollActiveRunStopSignal(client, options.stopSignal.config);
|
|
4742
|
+
}
|
|
4743
|
+
let response;
|
|
4744
|
+
try {
|
|
4745
|
+
response = await client.post(import_agent_runs2.AGENT_RUNS_ROUTES.claimAgentRuns(), {
|
|
4746
|
+
projectId,
|
|
4747
|
+
limit: claimLimit
|
|
4748
|
+
});
|
|
4749
|
+
consecutiveFailures = 0;
|
|
4750
|
+
} catch (error) {
|
|
4751
|
+
if (!isTransientClaimError(error)) {
|
|
4752
|
+
throw error;
|
|
4753
|
+
}
|
|
4754
|
+
if (Date.now() >= deadline) {
|
|
4755
|
+
return { items: [], inflightRuns: [], timedOut: true };
|
|
4756
|
+
}
|
|
4757
|
+
consecutiveFailures += 1;
|
|
4758
|
+
const backoffMs = computeBackoffMs(consecutiveFailures, retryBaseMs, retryMaxMs);
|
|
4759
|
+
const remainingMs2 = deadline - Date.now();
|
|
4760
|
+
await sleepFn(Math.min(backoffMs, remainingMs2));
|
|
4761
|
+
continue;
|
|
4762
|
+
}
|
|
4763
|
+
if (response.items.length > 0) {
|
|
4764
|
+
return { items: response.items, inflightRuns: [], timedOut: false };
|
|
4765
|
+
}
|
|
4766
|
+
const inflightRuns = await fetchInflightAgentRuns(client, { projectId, limit: claimLimit });
|
|
4767
|
+
if (inflightRuns.length > 0) {
|
|
4768
|
+
return { items: [], inflightRuns, timedOut: false };
|
|
4769
|
+
}
|
|
4770
|
+
if (Date.now() >= deadline) {
|
|
4771
|
+
return { items: [], inflightRuns: [], timedOut: true };
|
|
4772
|
+
}
|
|
4773
|
+
const remainingMs = deadline - Date.now();
|
|
4774
|
+
const waitMs = Math.min(pollIntervalMs, remainingMs);
|
|
4775
|
+
await sleepFn(waitMs);
|
|
4776
|
+
}
|
|
4777
|
+
}
|
|
4778
|
+
|
|
4779
|
+
// src/orchestrator/orchestrator-transport.ts
|
|
4780
|
+
var OrchestratorTransport = class {
|
|
4781
|
+
constructor(client, options = {}) {
|
|
4782
|
+
this.client = client;
|
|
4783
|
+
this.options = options;
|
|
4784
|
+
}
|
|
4785
|
+
async claimAndPoll(options, deps) {
|
|
4786
|
+
return pollAgentRuns(this.client, options, deps);
|
|
4787
|
+
}
|
|
4788
|
+
async fetchInflightRuns(projectId, limit) {
|
|
4789
|
+
return fetchInflightAgentRuns(this.client, { projectId, limit });
|
|
4790
|
+
}
|
|
4791
|
+
async ackRun(agentRunId, note) {
|
|
4792
|
+
const body = note !== void 0 ? { note } : void 0;
|
|
4793
|
+
return this.client.patch(import_agent_runs3.AGENT_RUNS_ROUTES.acknowledgeAgentRun(agentRunId), body);
|
|
4794
|
+
}
|
|
4795
|
+
async setAttention(agentRunId, requiresAttention, message) {
|
|
4796
|
+
const body = requiresAttention ? { requiresAttention: true, attentionMessage: message ?? "" } : { requiresAttention: false };
|
|
4797
|
+
return this.client.patch(import_agent_runs3.AGENT_RUNS_ROUTES.setAgentRunAttention(agentRunId), body);
|
|
4798
|
+
}
|
|
4799
|
+
async completeRun(agentRunId, body) {
|
|
4800
|
+
return this.client.post(import_agent_runs3.AGENT_RUNS_ROUTES.completeAgentRun(agentRunId), body);
|
|
4801
|
+
}
|
|
4802
|
+
async listAttachments(workItemId) {
|
|
4803
|
+
return fetchAttachments(this.client, workItemId);
|
|
4804
|
+
}
|
|
4805
|
+
async downloadAttachments(workItemId, workspaceRoot, attachmentIds) {
|
|
4806
|
+
return downloadWorkItemAttachments(this.client, {
|
|
4807
|
+
workItemId,
|
|
4808
|
+
workspaceRoot,
|
|
4809
|
+
attachmentIds,
|
|
4810
|
+
blockSensitiveAttachments: this.options.blockSensitiveAttachments ?? true
|
|
4811
|
+
});
|
|
4812
|
+
}
|
|
4813
|
+
async syncSubagents(projectId, workspaceRoot) {
|
|
4814
|
+
return syncProjectSubagents(this.client, { projectId, workspaceRoot });
|
|
4815
|
+
}
|
|
4816
|
+
async createComment(workItemId, body) {
|
|
4817
|
+
return postComment(this.client, workItemId, body);
|
|
4818
|
+
}
|
|
4819
|
+
};
|
|
4820
|
+
function createOrchestratorTransport(client, config) {
|
|
4821
|
+
return new OrchestratorTransport(client, {
|
|
4822
|
+
workspaceRoot: config?.workspaceRoot,
|
|
4823
|
+
blockSensitiveAttachments: config?.blockSensitiveAttachments
|
|
4824
|
+
});
|
|
4825
|
+
}
|
|
4826
|
+
|
|
4827
|
+
// src/workspace/parse-task-boards-yaml.ts
|
|
4828
|
+
import { existsSync as existsSync5, readFileSync as readFileSync3 } from "node:fs";
|
|
4829
|
+
import { join as join4 } from "node:path";
|
|
4830
|
+
var TASK_BOARDS_FILE2 = ".task-boards.yaml";
|
|
4831
|
+
var VERSION_PATTERN = /^\s*version\s*:\s*1\s*$/m;
|
|
4832
|
+
var PROJECT_ID_PATTERN = /^\s*projectId\s*:\s*["']?([0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})["']?\s*$/im;
|
|
4833
|
+
function parseTaskBoardsYaml(workspaceRoot) {
|
|
4834
|
+
const filePath = join4(workspaceRoot, TASK_BOARDS_FILE2);
|
|
4835
|
+
if (!existsSync5(filePath)) {
|
|
4836
|
+
return null;
|
|
4837
|
+
}
|
|
4838
|
+
const content = readFileSync3(filePath, "utf8");
|
|
4839
|
+
if (!VERSION_PATTERN.test(content)) {
|
|
4840
|
+
return null;
|
|
4841
|
+
}
|
|
4842
|
+
const match = PROJECT_ID_PATTERN.exec(content);
|
|
4843
|
+
if (match === null) {
|
|
4844
|
+
return null;
|
|
4845
|
+
}
|
|
4846
|
+
return match[1] ?? null;
|
|
4847
|
+
}
|
|
4848
|
+
|
|
4849
|
+
// src/tools/orchestrator-attention.util.ts
|
|
4850
|
+
var import_agent_run_status2 = __toESM(require_agent_run_status_enum(), 1);
|
|
4555
4851
|
var ATTENTION_MESSAGE_CATEGORY = {
|
|
4556
4852
|
SHELL: "shell",
|
|
4557
4853
|
GIT: "git",
|
|
@@ -4706,7 +5002,7 @@ function buildSmartModeAttentionMessage(toolName, reason) {
|
|
|
4706
5002
|
}
|
|
4707
5003
|
|
|
4708
5004
|
// src/attention/hook-payload.util.ts
|
|
4709
|
-
function
|
|
5005
|
+
function isRecord3(value) {
|
|
4710
5006
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4711
5007
|
}
|
|
4712
5008
|
function readString(record, key) {
|
|
@@ -4723,7 +5019,7 @@ function parseHookPayloadJson(raw) {
|
|
|
4723
5019
|
}
|
|
4724
5020
|
try {
|
|
4725
5021
|
const parsed = JSON.parse(trimmed);
|
|
4726
|
-
if (!
|
|
5022
|
+
if (!isRecord3(parsed)) {
|
|
4727
5023
|
return null;
|
|
4728
5024
|
}
|
|
4729
5025
|
return parsed;
|
|
@@ -5029,6 +5325,10 @@ function isAttentionCliInvocation(argv) {
|
|
|
5029
5325
|
return topLevel === "attention" || topLevel === "orchestrator";
|
|
5030
5326
|
}
|
|
5031
5327
|
|
|
5328
|
+
// src/cli-help.ts
|
|
5329
|
+
import { readFileSync as readFileSync4 } from "node:fs";
|
|
5330
|
+
import { join as join5 } from "node:path";
|
|
5331
|
+
|
|
5032
5332
|
// src/config.ts
|
|
5033
5333
|
var import_api = __toESM(require_build(), 1);
|
|
5034
5334
|
function resolveSanitizeResponses() {
|
|
@@ -5047,15 +5347,22 @@ function resolveBlockSensitiveAttachments() {
|
|
|
5047
5347
|
const normalized = raw.trim().toLowerCase();
|
|
5048
5348
|
return normalized !== "false" && normalized !== "0" && normalized !== "no";
|
|
5049
5349
|
}
|
|
5350
|
+
function resolveApiUrlFromEnv(env = process.env) {
|
|
5351
|
+
const rawBaseUrl = (env.TASK_BOARDS_API_URL ?? "http://localhost:3000").replace(/\/$/, "");
|
|
5352
|
+
return {
|
|
5353
|
+
rawBaseUrl,
|
|
5354
|
+
effectiveApiUrl: `${rawBaseUrl}${import_api.API_V1_PREFIX}`
|
|
5355
|
+
};
|
|
5356
|
+
}
|
|
5050
5357
|
function loadConfig() {
|
|
5051
|
-
const
|
|
5358
|
+
const { effectiveApiUrl } = resolveApiUrlFromEnv();
|
|
5052
5359
|
const apiToken = process.env.TASK_BOARDS_API_TOKEN;
|
|
5053
5360
|
const workspaceRoot = process.env.WORKSPACE_ROOT;
|
|
5054
5361
|
if (process.env.NODE_ENV === "production" && (apiToken === void 0 || apiToken.trim() === "")) {
|
|
5055
5362
|
console.error("WARNING: TASK_BOARDS_API_TOKEN is not set. MCP server cannot authenticate to the Task Boards API.");
|
|
5056
5363
|
}
|
|
5057
5364
|
return {
|
|
5058
|
-
apiUrl:
|
|
5365
|
+
apiUrl: effectiveApiUrl,
|
|
5059
5366
|
apiToken,
|
|
5060
5367
|
workspaceRoot: workspaceRoot !== void 0 && workspaceRoot.trim() !== "" ? workspaceRoot : void 0,
|
|
5061
5368
|
sanitizeResponses: resolveSanitizeResponses(),
|
|
@@ -5063,13 +5370,412 @@ function loadConfig() {
|
|
|
5063
5370
|
};
|
|
5064
5371
|
}
|
|
5065
5372
|
|
|
5373
|
+
// src/cli-help.ts
|
|
5374
|
+
var NPM_README_URL = "https://www.npmjs.com/package/@task-boards/mcp-server#readme";
|
|
5375
|
+
var CLI_ENV_VARS = [
|
|
5376
|
+
{
|
|
5377
|
+
name: "TASK_BOARDS_API_URL",
|
|
5378
|
+
required: "No",
|
|
5379
|
+
defaultDisplay: "http://localhost:3000",
|
|
5380
|
+
description: "Task Boards backend base URL (without /api/v1 suffix)"
|
|
5381
|
+
},
|
|
5382
|
+
{
|
|
5383
|
+
name: "TASK_BOARDS_API_TOKEN",
|
|
5384
|
+
required: "Yes in production",
|
|
5385
|
+
defaultDisplay: "(unset \u2014 value never printed)",
|
|
5386
|
+
description: "API token with read / write scopes"
|
|
5387
|
+
},
|
|
5388
|
+
{
|
|
5389
|
+
name: "WORKSPACE_ROOT",
|
|
5390
|
+
required: "No",
|
|
5391
|
+
defaultDisplay: "(unset)",
|
|
5392
|
+
description: "Git repo root for attachments, sync tools, and orchestrator bridge state"
|
|
5393
|
+
},
|
|
5394
|
+
{
|
|
5395
|
+
name: "TASK_BOARDS_MCP_SANITIZE",
|
|
5396
|
+
required: "No",
|
|
5397
|
+
defaultDisplay: "true (enabled)",
|
|
5398
|
+
description: "Sanitize MCP tool responses; set false, 0, or no to disable"
|
|
5399
|
+
},
|
|
5400
|
+
{
|
|
5401
|
+
name: "TASK_BOARDS_MCP_BLOCK_SENSITIVE_ATTACHMENTS",
|
|
5402
|
+
required: "No",
|
|
5403
|
+
defaultDisplay: "true (enabled)",
|
|
5404
|
+
description: "Block sensitive attachment paths; set false, 0, or no to disable"
|
|
5405
|
+
}
|
|
5406
|
+
];
|
|
5407
|
+
var CLI_TOOL_CATALOG = [
|
|
5408
|
+
{
|
|
5409
|
+
name: "list_projects",
|
|
5410
|
+
description: "List task-boards projects (non-archived by default)."
|
|
5411
|
+
},
|
|
5412
|
+
{
|
|
5413
|
+
name: "get_project",
|
|
5414
|
+
description: "Get a project by id."
|
|
5415
|
+
},
|
|
5416
|
+
{
|
|
5417
|
+
name: "create_project",
|
|
5418
|
+
description: "Create a project and its board from the selected preset."
|
|
5419
|
+
},
|
|
5420
|
+
{
|
|
5421
|
+
name: "update_project",
|
|
5422
|
+
description: "Update project settings (name, description, estimation mode/required, task card estimation display, subagent role bindings). Requires write scope."
|
|
5423
|
+
},
|
|
5424
|
+
{
|
|
5425
|
+
name: "resolve_project",
|
|
5426
|
+
description: "Resolve the task-boards project for the current workspace (.task-boards.yaml, .cursor/rules, or folder name auto-match)."
|
|
5427
|
+
},
|
|
5428
|
+
{
|
|
5429
|
+
name: "list_work_items",
|
|
5430
|
+
description: "List work items for a project."
|
|
5431
|
+
},
|
|
5432
|
+
{
|
|
5433
|
+
name: "search_work_items",
|
|
5434
|
+
description: "Search work items by query string (title, description, acceptance criteria, display key)."
|
|
5435
|
+
},
|
|
5436
|
+
{
|
|
5437
|
+
name: "get_work_item",
|
|
5438
|
+
description: "Get a work item by id."
|
|
5439
|
+
},
|
|
5440
|
+
{
|
|
5441
|
+
name: "create_work_item",
|
|
5442
|
+
description: "Create a work item under a project. MCP/automation attributes creator and default assignee to the \xAB\u0410\u0433\u0435\u043D\u0442 \u0418\u0418\xBB service user (UserKind.SERVICE) unless assigneeUserId is set. The AI orchestrator processes STORY items only when assignee is that service user. Priority defaults to LOW when omitted. storyPoints and estimate are optional on create; when project.estimationRequired is true they are required before moving a STORY to any column except backlog (slug=backlog)."
|
|
5443
|
+
},
|
|
5444
|
+
{
|
|
5445
|
+
name: "update_work_item",
|
|
5446
|
+
description: "Update work item fields (fetches current version first)."
|
|
5447
|
+
},
|
|
5448
|
+
{
|
|
5449
|
+
name: "move_work_item",
|
|
5450
|
+
description: "Move a work item to another board column (fetches current version first). When project.estimationRequired is true, returns ESTIMATION_REQUIRED_FOR_MOVE (422) if the STORY lacks active storyPoints or estimate (per estimationMode) and the target column slug is not backlog."
|
|
5451
|
+
},
|
|
5452
|
+
{
|
|
5453
|
+
name: "get_work_item_delete_preview",
|
|
5454
|
+
description: "Preview hard-delete impact for a work item (cascade counts and eligibility). MCP may delete SUBTASK items only."
|
|
5455
|
+
},
|
|
5456
|
+
{
|
|
5457
|
+
name: "delete_work_item",
|
|
5458
|
+
description: "Hard-delete a SUBTASK work item (leaf delete with confirmCascade false). EPIC/STORY deletes are human-only."
|
|
5459
|
+
},
|
|
5460
|
+
{
|
|
5461
|
+
name: "list_comments",
|
|
5462
|
+
description: "List comments for a work item (newest last)."
|
|
5463
|
+
},
|
|
5464
|
+
{
|
|
5465
|
+
name: "create_comment",
|
|
5466
|
+
description: "Create a comment on a work item. Use for orchestrator NEEDS_CLARIFICATION questions before complete_agent_run."
|
|
5467
|
+
},
|
|
5468
|
+
{
|
|
5469
|
+
name: "list_labels",
|
|
5470
|
+
description: "List labels for a project."
|
|
5471
|
+
},
|
|
5472
|
+
{
|
|
5473
|
+
name: "create_label",
|
|
5474
|
+
description: "Create a project label."
|
|
5475
|
+
},
|
|
5476
|
+
{
|
|
5477
|
+
name: "update_label",
|
|
5478
|
+
description: "Update a project label."
|
|
5479
|
+
},
|
|
5480
|
+
{
|
|
5481
|
+
name: "delete_label",
|
|
5482
|
+
description: "Delete a project label."
|
|
5483
|
+
},
|
|
5484
|
+
{
|
|
5485
|
+
name: "list_work_item_attachments",
|
|
5486
|
+
description: "List file attachments for a work item."
|
|
5487
|
+
},
|
|
5488
|
+
{
|
|
5489
|
+
name: "download_work_item_attachments",
|
|
5490
|
+
description: "Download work item attachments into the local workspace staging directory (.task-boards/attachments)."
|
|
5491
|
+
},
|
|
5492
|
+
{
|
|
5493
|
+
name: "upload_work_item_attachment",
|
|
5494
|
+
description: "Upload a local workspace file as a work item attachment (multipart field file)."
|
|
5495
|
+
},
|
|
5496
|
+
{
|
|
5497
|
+
name: "get_board",
|
|
5498
|
+
description: "Get board projection for a project (columns and on-board work items)."
|
|
5499
|
+
},
|
|
5500
|
+
{
|
|
5501
|
+
name: "list_agent_runs",
|
|
5502
|
+
description: "List agent runs for a project (default status PENDING). Prefer wait_for_agent_runs for orchestrator long-polling."
|
|
5503
|
+
},
|
|
5504
|
+
{
|
|
5505
|
+
name: "wait_for_agent_runs",
|
|
5506
|
+
description: "Long-poll agent runs for a project: atomically claims PENDING runs (POST /agent-runs/claim). On empty claim, immediately lists inflight DISPATCHED/ACKNOWLEDGED runs (GET activeOnly) for orphan recovery before sleeping. Returns items (newly claimed), inflightRuns (resume candidates), and orchestrator hints. First claim is immediate; subsequent polls sleep pollInterval seconds only when both claim and inflight are empty."
|
|
5507
|
+
},
|
|
5508
|
+
{
|
|
5509
|
+
name: "ack_agent_run",
|
|
5510
|
+
description: "Acknowledge agent run delivery after Task subagent has been dispatched. Requires status DISPATCHED (DISPATCHED \u2192 ACKNOWLEDGED)."
|
|
5511
|
+
},
|
|
5512
|
+
{
|
|
5513
|
+
name: "report_agent_attention",
|
|
5514
|
+
description: "Signal that the in-flight subagent needs human attention while the run is ACKNOWLEDGED. Sets requiresAttention on the agent run for orchestrator/UI visibility."
|
|
5515
|
+
},
|
|
5516
|
+
{
|
|
5517
|
+
name: "clear_agent_attention",
|
|
5518
|
+
description: "Clear the human-attention flag after the blocker is resolved. Requires the run to still be ACKNOWLEDGED."
|
|
5519
|
+
},
|
|
5520
|
+
{
|
|
5521
|
+
name: "complete_agent_run",
|
|
5522
|
+
description: "Complete agent run: apply AGENTIC_SDLC workflow transition and optional work item patch. AGENTIC_SDLC has 7 columns: backlog, in-analysis (PRODUCT\u2192ANALYST\u2192ARCHITECT handoffs), in-development (DESIGNER optional, then parallel FRONTEND_DEVELOPER+DEVELOPER), in-qa, in-awaiting, done, released. Outcomes: Prerequisite: STORY assignee must be \u0410\u0433\u0435\u043D\u0442 \u0418\u0418 (SERVICE user) \u2014 otherwise no agent_run is enqueued or claimed. in-analysis: PRODUCT/ANALYST DEFAULT \u2192 HANDOFF next phase (skip unbound roles); ANALYST SKIP_DESIGN \u2192 in-development; ANALYST SKIP_DEV \u2192 released when codeChangesRequired=false (no git commit); ARCHITECT DEFAULT \u2192 in-development (set workItemPatch.designerRequired). in-development: DESIGNER DEFAULT \u2192 DEVELOPMENT; dev role DEFAULT removes role from pendingDevRoles, moves to in-qa when empty; SKIP_DESIGN skips DESIGNER. in-qa: DEFAULT \u2192 done; HAS_BUGS \u2192 in-development (re-init pendingDevRoles). NEEDS_CLARIFICATION \u2192 in-awaiting. FAILED \u2192 no move. Claim priority: in-development > in-qa > in-analysis (SERVICE-assigned stories only block analysis)."
|
|
5523
|
+
},
|
|
5524
|
+
{
|
|
5525
|
+
name: "run_orchestrator_once",
|
|
5526
|
+
description: "Resolve project (if needed), long-poll agent runs with atomic claim, and return orchestrator hints. Claims only STORY items assigned to \u0410\u0433\u0435\u043D\u0442 \u0418\u0418 (SERVICE user). Does not call sync_git_releases \u2014 the orchestrator agent decides when to sync."
|
|
5527
|
+
},
|
|
5528
|
+
{
|
|
5529
|
+
name: "sync_git_releases",
|
|
5530
|
+
description: "Fetch origin and sync commits tagged with work-item:{uuid} from the default branch (master/main) and, when cwd is on a feature branch, the current branch too. Use after git push on feature branches; on master/main local commit only. Requires MCP API token with write scope."
|
|
5531
|
+
},
|
|
5532
|
+
{
|
|
5533
|
+
name: "sync_project_subagents",
|
|
5534
|
+
description: "Sync project custom subagent definitions from the API to {workspaceRoot}/.cursor/agents/{slug}.md so the IDE Task tool can resolve custom slugs. Idempotent overwrite. Requires MCP API token with write scope."
|
|
5535
|
+
}
|
|
5536
|
+
];
|
|
5537
|
+
var CLI_AUX_MODES = [
|
|
5538
|
+
{
|
|
5539
|
+
invocation: "task-boards-mcp",
|
|
5540
|
+
description: "Default: MCP stdio server for IDE clients"
|
|
5541
|
+
},
|
|
5542
|
+
{
|
|
5543
|
+
invocation: "task-boards-mcp attention report",
|
|
5544
|
+
description: "Report IDE attention for an in-flight agent run (orchestrator hooks)"
|
|
5545
|
+
},
|
|
5546
|
+
{
|
|
5547
|
+
invocation: "task-boards-mcp attention report-from-hook",
|
|
5548
|
+
description: "Report IDE attention from Cursor hook stdin payload"
|
|
5549
|
+
},
|
|
5550
|
+
{
|
|
5551
|
+
invocation: "task-boards-mcp attention clear",
|
|
5552
|
+
description: "Clear local attention pending state"
|
|
5553
|
+
},
|
|
5554
|
+
{
|
|
5555
|
+
invocation: "task-boards-mcp orchestrator write-active-run",
|
|
5556
|
+
description: "Persist active agent run state to workspace bridge files"
|
|
5557
|
+
},
|
|
5558
|
+
{
|
|
5559
|
+
invocation: "task-boards-mcp orchestrator clear-active-run",
|
|
5560
|
+
description: "Clear orchestrator bridge state from workspace"
|
|
5561
|
+
},
|
|
5562
|
+
{
|
|
5563
|
+
invocation: "task-boards-mcp skills install [--global]",
|
|
5564
|
+
description: "Install bundled Task Boards Cursor skills to .cursor/skills/ (project) or ~/.cursor/skills/ (--global)"
|
|
5565
|
+
}
|
|
5566
|
+
];
|
|
5567
|
+
function isHelpInvocation(argv) {
|
|
5568
|
+
const topLevel = argv[0];
|
|
5569
|
+
return topLevel === "-h" || topLevel === "--help";
|
|
5570
|
+
}
|
|
5571
|
+
function readPackageMeta() {
|
|
5572
|
+
const pkgPath = join5(__dirname, "../package.json");
|
|
5573
|
+
const pkg = JSON.parse(readFileSync4(pkgPath, "utf8"));
|
|
5574
|
+
return {
|
|
5575
|
+
name: pkg.name,
|
|
5576
|
+
version: pkg.version
|
|
5577
|
+
};
|
|
5578
|
+
}
|
|
5579
|
+
function formatEnvSection(env) {
|
|
5580
|
+
const lines = ["ENVIRONMENT"];
|
|
5581
|
+
for (const variable of CLI_ENV_VARS) {
|
|
5582
|
+
lines.push(` ${variable.name}`);
|
|
5583
|
+
lines.push(` Required: ${variable.required}`);
|
|
5584
|
+
lines.push(` Default: ${variable.defaultDisplay}`);
|
|
5585
|
+
lines.push(` ${variable.description}`);
|
|
5586
|
+
lines.push("");
|
|
5587
|
+
}
|
|
5588
|
+
const { effectiveApiUrl } = resolveApiUrlFromEnv(env);
|
|
5589
|
+
lines.push(" Effective API base: {TASK_BOARDS_API_URL without trailing slash}/api/v1");
|
|
5590
|
+
lines.push(` Example default: ${effectiveApiUrl}`);
|
|
5591
|
+
return lines.join("\n");
|
|
5592
|
+
}
|
|
5593
|
+
function formatToolsSection() {
|
|
5594
|
+
const lines = [`MCP TOOLS (${CLI_TOOL_CATALOG.length})`];
|
|
5595
|
+
for (const tool of CLI_TOOL_CATALOG) {
|
|
5596
|
+
lines.push(` ${tool.name} \u2014 ${tool.description}`);
|
|
5597
|
+
}
|
|
5598
|
+
return lines.join("\n");
|
|
5599
|
+
}
|
|
5600
|
+
function formatAuxModesSection() {
|
|
5601
|
+
const lines = ["AUXILIARY CLI MODES"];
|
|
5602
|
+
for (const mode of CLI_AUX_MODES) {
|
|
5603
|
+
lines.push(` ${mode.invocation}`);
|
|
5604
|
+
lines.push(` ${mode.description}`);
|
|
5605
|
+
}
|
|
5606
|
+
lines.push("");
|
|
5607
|
+
lines.push(" attention report|report-from-hook|clear");
|
|
5608
|
+
lines.push(" orchestrator write-active-run|clear-active-run");
|
|
5609
|
+
lines.push(" skills install [--global]");
|
|
5610
|
+
return lines.join("\n");
|
|
5611
|
+
}
|
|
5612
|
+
function formatCliHelp(options = {}) {
|
|
5613
|
+
const packageMeta = options.packageMeta ?? readPackageMeta();
|
|
5614
|
+
const env = options.env ?? process.env;
|
|
5615
|
+
const sections = [
|
|
5616
|
+
`${packageMeta.name} ${packageMeta.version}`,
|
|
5617
|
+
"",
|
|
5618
|
+
"USAGE",
|
|
5619
|
+
" task-boards-mcp [--help|-h]",
|
|
5620
|
+
" task-boards-mcp [attention|orchestrator ...] # auxiliary bridge modes",
|
|
5621
|
+
" task-boards-mcp skills install [--global] # install bundled Cursor skills",
|
|
5622
|
+
" task-boards-mcp # default: MCP stdio server",
|
|
5623
|
+
"",
|
|
5624
|
+
formatEnvSection(env),
|
|
5625
|
+
"",
|
|
5626
|
+
formatToolsSection(),
|
|
5627
|
+
"",
|
|
5628
|
+
formatAuxModesSection(),
|
|
5629
|
+
"",
|
|
5630
|
+
"DOCUMENTATION",
|
|
5631
|
+
` Orchestrator loop, IDE MCP config: ${NPM_README_URL}`,
|
|
5632
|
+
" Local development: packages/mcp-server/README.md",
|
|
5633
|
+
""
|
|
5634
|
+
];
|
|
5635
|
+
return sections.join("\n");
|
|
5636
|
+
}
|
|
5637
|
+
|
|
5638
|
+
// src/skills/install-bundled-skills.ts
|
|
5639
|
+
import { copyFileSync, existsSync as existsSync6, mkdirSync as mkdirSync3 } from "node:fs";
|
|
5640
|
+
import { join as join6 } from "node:path";
|
|
5641
|
+
|
|
5642
|
+
// src/skills/bundled-skills-catalog.ts
|
|
5643
|
+
var BUNDLED_SKILL_NAMES = [
|
|
5644
|
+
"task-boards-setup",
|
|
5645
|
+
"task-boards-orchestrator",
|
|
5646
|
+
"task-boards-work-items",
|
|
5647
|
+
"task-boards-agent-runs",
|
|
5648
|
+
"task-boards-attention",
|
|
5649
|
+
"task-boards-git-sync"
|
|
5650
|
+
];
|
|
5651
|
+
|
|
5652
|
+
// src/skills/install-bundled-skills.ts
|
|
5653
|
+
var BundledSkillsError = class extends Error {
|
|
5654
|
+
constructor(message) {
|
|
5655
|
+
super(message);
|
|
5656
|
+
this.name = "BundledSkillsError";
|
|
5657
|
+
}
|
|
5658
|
+
};
|
|
5659
|
+
function installBundledSkills(params) {
|
|
5660
|
+
const { bundledSkillsRoot, targetSkillsRoot } = params;
|
|
5661
|
+
const packageMeta = readPackageMeta();
|
|
5662
|
+
mkdirSync3(targetSkillsRoot, { recursive: true });
|
|
5663
|
+
const skills = [];
|
|
5664
|
+
for (const skillName of BUNDLED_SKILL_NAMES) {
|
|
5665
|
+
const srcFile = join6(bundledSkillsRoot, skillName, "SKILL.md");
|
|
5666
|
+
if (!existsSync6(srcFile)) {
|
|
5667
|
+
throw new BundledSkillsError(`Missing bundled skill file: ${srcFile}`);
|
|
5668
|
+
}
|
|
5669
|
+
const destDir = join6(targetSkillsRoot, skillName);
|
|
5670
|
+
const destFile = join6(destDir, "SKILL.md");
|
|
5671
|
+
const action = existsSync6(destFile) ? "overwritten" : "installed";
|
|
5672
|
+
mkdirSync3(destDir, { recursive: true });
|
|
5673
|
+
copyFileSync(srcFile, destFile);
|
|
5674
|
+
skills.push({
|
|
5675
|
+
skillName,
|
|
5676
|
+
targetPath: destFile,
|
|
5677
|
+
action
|
|
5678
|
+
});
|
|
5679
|
+
}
|
|
5680
|
+
return {
|
|
5681
|
+
targetDirectory: targetSkillsRoot,
|
|
5682
|
+
packageName: packageMeta.name,
|
|
5683
|
+
packageVersion: packageMeta.version,
|
|
5684
|
+
skills
|
|
5685
|
+
};
|
|
5686
|
+
}
|
|
5687
|
+
|
|
5688
|
+
// src/skills/resolve-bundled-skills-root.ts
|
|
5689
|
+
import { homedir } from "node:os";
|
|
5690
|
+
import { join as join7 } from "node:path";
|
|
5691
|
+
function resolveBundledSkillsRoot() {
|
|
5692
|
+
return join7(__dirname, "../skills");
|
|
5693
|
+
}
|
|
5694
|
+
function resolveProjectSkillsTarget(workspaceRoot) {
|
|
5695
|
+
return join7(workspaceRoot, ".cursor", "skills");
|
|
5696
|
+
}
|
|
5697
|
+
function resolveGlobalSkillsTarget(homeDirectory = homedir()) {
|
|
5698
|
+
return join7(homeDirectory, ".cursor", "skills");
|
|
5699
|
+
}
|
|
5700
|
+
|
|
5701
|
+
// src/skills/skills-cli.ts
|
|
5702
|
+
function defaultLog(message) {
|
|
5703
|
+
process.stdout.write(`${message}
|
|
5704
|
+
`);
|
|
5705
|
+
}
|
|
5706
|
+
function defaultLogError(message) {
|
|
5707
|
+
process.stderr.write(`${message}
|
|
5708
|
+
`);
|
|
5709
|
+
}
|
|
5710
|
+
function isSkillsCliInvocation(argv) {
|
|
5711
|
+
return argv[0] === "skills";
|
|
5712
|
+
}
|
|
5713
|
+
function hasGlobalFlag(argv) {
|
|
5714
|
+
return argv.includes("--global");
|
|
5715
|
+
}
|
|
5716
|
+
function formatSkillsInstallSummary(result) {
|
|
5717
|
+
const lines = [
|
|
5718
|
+
`Installed Task Boards skills (${result.packageName} ${result.packageVersion})`,
|
|
5719
|
+
`Target: ${result.targetDirectory}`,
|
|
5720
|
+
""
|
|
5721
|
+
];
|
|
5722
|
+
for (const skill of result.skills) {
|
|
5723
|
+
lines.push(` ${skill.skillName}: ${skill.action}`);
|
|
5724
|
+
}
|
|
5725
|
+
return lines.join("\n");
|
|
5726
|
+
}
|
|
5727
|
+
function runSkillsCli(argv, deps = {}) {
|
|
5728
|
+
const log = deps.log ?? defaultLog;
|
|
5729
|
+
const logError = deps.logError ?? defaultLogError;
|
|
5730
|
+
const installFn = deps.installFn ?? installBundledSkills;
|
|
5731
|
+
const resolveBundledRoot = deps.resolveBundledRoot ?? resolveBundledSkillsRoot;
|
|
5732
|
+
const resolveWorkspace = deps.resolveWorkspace ?? resolveWorkspaceRoot;
|
|
5733
|
+
const resolveGlobalTarget = deps.resolveGlobalTarget ?? resolveGlobalSkillsTarget;
|
|
5734
|
+
const subcommand = argv[1];
|
|
5735
|
+
if (subcommand !== "install") {
|
|
5736
|
+
logError("Usage: task-boards-mcp skills install [--global]");
|
|
5737
|
+
return 1;
|
|
5738
|
+
}
|
|
5739
|
+
const isGlobal = hasGlobalFlag(argv);
|
|
5740
|
+
let targetSkillsRoot;
|
|
5741
|
+
try {
|
|
5742
|
+
if (isGlobal) {
|
|
5743
|
+
targetSkillsRoot = resolveGlobalTarget();
|
|
5744
|
+
} else {
|
|
5745
|
+
const config = loadConfig();
|
|
5746
|
+
const workspaceRoot = resolveWorkspace(void 0, config.workspaceRoot);
|
|
5747
|
+
targetSkillsRoot = resolveProjectSkillsTarget(workspaceRoot);
|
|
5748
|
+
}
|
|
5749
|
+
} catch (error) {
|
|
5750
|
+
const message = error instanceof Error ? error.message : "Failed to resolve skills install target";
|
|
5751
|
+
logError(message);
|
|
5752
|
+
return 1;
|
|
5753
|
+
}
|
|
5754
|
+
try {
|
|
5755
|
+
const result = installFn({
|
|
5756
|
+
bundledSkillsRoot: resolveBundledRoot(),
|
|
5757
|
+
targetSkillsRoot
|
|
5758
|
+
});
|
|
5759
|
+
log(formatSkillsInstallSummary(result));
|
|
5760
|
+
return 0;
|
|
5761
|
+
} catch (error) {
|
|
5762
|
+
if (error instanceof BundledSkillsError) {
|
|
5763
|
+
logError(error.message);
|
|
5764
|
+
return 1;
|
|
5765
|
+
}
|
|
5766
|
+
const message = error instanceof Error ? error.message : "Failed to install bundled skills";
|
|
5767
|
+
logError(message);
|
|
5768
|
+
return 1;
|
|
5769
|
+
}
|
|
5770
|
+
}
|
|
5771
|
+
|
|
5066
5772
|
// src/index.ts
|
|
5067
5773
|
import { createRequire } from "node:module";
|
|
5068
5774
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5069
5775
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5070
5776
|
|
|
5071
5777
|
// src/tools/agent-runs.ts
|
|
5072
|
-
var
|
|
5778
|
+
var import_agent_runs4 = __toESM(require_agent_runs_api(), 1);
|
|
5073
5779
|
var import_agent_run_outcome = __toESM(require_agent_run_outcome_enum(), 1);
|
|
5074
5780
|
var import_agent_run_status4 = __toESM(require_agent_run_status_enum(), 1);
|
|
5075
5781
|
import { z as z3 } from "zod";
|
|
@@ -5325,7 +6031,7 @@ function registerAgentRunTools(server, client, config) {
|
|
|
5325
6031
|
},
|
|
5326
6032
|
async ({ status, projectId }) => runTool(async () => {
|
|
5327
6033
|
const effectiveStatus = status ?? import_agent_run_status4.AGENT_RUN_STATUS.PENDING;
|
|
5328
|
-
return client.get(
|
|
6034
|
+
return client.get(import_agent_runs4.AGENT_RUNS_ROUTES.listAgentRuns(), {
|
|
5329
6035
|
status: effectiveStatus,
|
|
5330
6036
|
projectId
|
|
5331
6037
|
});
|
|
@@ -5347,7 +6053,8 @@ function registerAgentRunTools(server, client, config) {
|
|
|
5347
6053
|
projectId,
|
|
5348
6054
|
timeoutMs: timeout * 1e3,
|
|
5349
6055
|
pollIntervalMs: pollInterval * 1e3,
|
|
5350
|
-
limit
|
|
6056
|
+
limit,
|
|
6057
|
+
stopSignal: { config }
|
|
5351
6058
|
});
|
|
5352
6059
|
return enrichPollResult(pollResult.items, pollResult.inflightRuns, pollResult.timedOut);
|
|
5353
6060
|
})
|
|
@@ -5363,8 +6070,13 @@ function registerAgentRunTools(server, client, config) {
|
|
|
5363
6070
|
},
|
|
5364
6071
|
async ({ agentRunId, note }) => runTool(async () => {
|
|
5365
6072
|
const body = note !== void 0 ? { note } : void 0;
|
|
5366
|
-
const response = await client.patch(
|
|
6073
|
+
const response = await client.patch(import_agent_runs4.AGENT_RUNS_ROUTES.acknowledgeAgentRun(agentRunId), body);
|
|
5367
6074
|
writeActiveRunFromAck(config, response);
|
|
6075
|
+
try {
|
|
6076
|
+
await client.post(import_agent_runs4.AGENT_RUNS_ROUTES.registerAgentRunProcess(agentRunId), { pid: process.pid });
|
|
6077
|
+
registerLocalProcess(agentRunId, response.workItemId, process.pid);
|
|
6078
|
+
} catch {
|
|
6079
|
+
}
|
|
5368
6080
|
return response;
|
|
5369
6081
|
})
|
|
5370
6082
|
);
|
|
@@ -5382,7 +6094,7 @@ function registerAgentRunTools(server, client, config) {
|
|
|
5382
6094
|
requiresAttention: true,
|
|
5383
6095
|
attentionMessage: message
|
|
5384
6096
|
};
|
|
5385
|
-
return client.patch(
|
|
6097
|
+
return client.patch(import_agent_runs4.AGENT_RUNS_ROUTES.setAgentRunAttention(agentRunId), body);
|
|
5386
6098
|
})
|
|
5387
6099
|
);
|
|
5388
6100
|
server.registerTool(
|
|
@@ -5397,7 +6109,7 @@ function registerAgentRunTools(server, client, config) {
|
|
|
5397
6109
|
const body = {
|
|
5398
6110
|
requiresAttention: false
|
|
5399
6111
|
};
|
|
5400
|
-
return client.patch(
|
|
6112
|
+
return client.patch(import_agent_runs4.AGENT_RUNS_ROUTES.setAgentRunAttention(agentRunId), body);
|
|
5401
6113
|
})
|
|
5402
6114
|
);
|
|
5403
6115
|
server.registerTool(
|
|
@@ -5430,10 +6142,15 @@ function registerAgentRunTools(server, client, config) {
|
|
|
5430
6142
|
}
|
|
5431
6143
|
const hasBody = outcome !== void 0 || note !== void 0 || workItemPatch !== void 0 && workItemPatch !== null;
|
|
5432
6144
|
const response = await client.post(
|
|
5433
|
-
|
|
6145
|
+
import_agent_runs4.AGENT_RUNS_ROUTES.completeAgentRun(agentRunId),
|
|
5434
6146
|
hasBody ? body : void 0
|
|
5435
6147
|
);
|
|
5436
6148
|
clearActiveRunAfterComplete(config);
|
|
6149
|
+
try {
|
|
6150
|
+
await client.delete(import_agent_runs4.AGENT_RUNS_ROUTES.unregisterAgentRunProcess(agentRunId));
|
|
6151
|
+
} catch {
|
|
6152
|
+
}
|
|
6153
|
+
unregisterLocalProcess(agentRunId);
|
|
5437
6154
|
return response;
|
|
5438
6155
|
})
|
|
5439
6156
|
);
|
|
@@ -5509,8 +6226,8 @@ function autoMatchProject(folderToken, projects) {
|
|
|
5509
6226
|
}
|
|
5510
6227
|
|
|
5511
6228
|
// src/workspace/parse-ide-rules.ts
|
|
5512
|
-
import { existsSync as
|
|
5513
|
-
import { join as
|
|
6229
|
+
import { existsSync as existsSync7, readdirSync, readFileSync as readFileSync5 } from "node:fs";
|
|
6230
|
+
import { join as join8 } from "node:path";
|
|
5514
6231
|
var PROJECT_ID_LINE_PATTERN = /projectId\s*[:=]\s*["']?([0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})/gi;
|
|
5515
6232
|
var TASK_BOARDS_UUID_PATTERN = /task-boards[^\n\r]*?([0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})/gi;
|
|
5516
6233
|
function extractUuids(content) {
|
|
@@ -5529,8 +6246,8 @@ function extractUuids(content) {
|
|
|
5529
6246
|
return ids;
|
|
5530
6247
|
}
|
|
5531
6248
|
function parseIdeRules(workspaceRoot) {
|
|
5532
|
-
const rulesDir =
|
|
5533
|
-
if (!
|
|
6249
|
+
const rulesDir = join8(workspaceRoot, ".cursor", "rules");
|
|
6250
|
+
if (!existsSync7(rulesDir)) {
|
|
5534
6251
|
return { status: "missing" };
|
|
5535
6252
|
}
|
|
5536
6253
|
const entries = readdirSync(rulesDir, { withFileTypes: true });
|
|
@@ -5542,7 +6259,7 @@ function parseIdeRules(workspaceRoot) {
|
|
|
5542
6259
|
if (!entry.name.endsWith(".mdc") && !entry.name.endsWith(".md")) {
|
|
5543
6260
|
continue;
|
|
5544
6261
|
}
|
|
5545
|
-
const content =
|
|
6262
|
+
const content = readFileSync5(join8(rulesDir, entry.name), "utf8");
|
|
5546
6263
|
for (const id of extractUuids(content)) {
|
|
5547
6264
|
allIds.add(id);
|
|
5548
6265
|
}
|
|
@@ -5643,8 +6360,12 @@ async function runOrchestratorOnce(client, options) {
|
|
|
5643
6360
|
projectId,
|
|
5644
6361
|
timeoutMs: options.timeoutMs,
|
|
5645
6362
|
pollIntervalMs: options.pollIntervalMs,
|
|
5646
|
-
limit: options.limit
|
|
6363
|
+
limit: options.limit,
|
|
6364
|
+
stopSignal: options.config !== void 0 ? { config: options.config } : void 0
|
|
5647
6365
|
});
|
|
6366
|
+
if (options.config !== void 0) {
|
|
6367
|
+
await pollActiveRunStopSignal(client, options.config);
|
|
6368
|
+
}
|
|
5648
6369
|
const enriched = enrichPollResult(pollResult.items, pollResult.inflightRuns, pollResult.timedOut);
|
|
5649
6370
|
return {
|
|
5650
6371
|
projectId,
|
|
@@ -5675,7 +6396,8 @@ function registerOrchestratorTools(server, client, config) {
|
|
|
5675
6396
|
pollIntervalMs: pollInterval * 1e3,
|
|
5676
6397
|
limit,
|
|
5677
6398
|
workspaceRootOverride: workspaceRoot,
|
|
5678
|
-
envWorkspaceRoot: config.workspaceRoot
|
|
6399
|
+
envWorkspaceRoot: config.workspaceRoot,
|
|
6400
|
+
config
|
|
5679
6401
|
})
|
|
5680
6402
|
)
|
|
5681
6403
|
);
|
|
@@ -6134,6 +6856,14 @@ async function deleteWorkItem(client, workItemId) {
|
|
|
6134
6856
|
const body = { confirmCascade: false };
|
|
6135
6857
|
await client.delete(import_work_items.WORK_ITEMS_ROUTES.deleteWorkItem(workItemId), body);
|
|
6136
6858
|
}
|
|
6859
|
+
async function patchWorkItemWithCurrentVersion(client, workItemId, fields) {
|
|
6860
|
+
const current = await client.get(import_work_items.WORK_ITEMS_ROUTES.getWorkItem(workItemId));
|
|
6861
|
+
const body = {
|
|
6862
|
+
...fields,
|
|
6863
|
+
version: current.version
|
|
6864
|
+
};
|
|
6865
|
+
return client.patch(import_work_items.WORK_ITEMS_ROUTES.updateWorkItem(workItemId), body);
|
|
6866
|
+
}
|
|
6137
6867
|
function registerWorkItemTools(server, client) {
|
|
6138
6868
|
server.registerTool(
|
|
6139
6869
|
"list_work_items",
|
|
@@ -6184,7 +6914,7 @@ function registerWorkItemTools(server, client) {
|
|
|
6184
6914
|
server.registerTool(
|
|
6185
6915
|
"create_work_item",
|
|
6186
6916
|
{
|
|
6187
|
-
description: "Create a work item under a project. MCP/automation attributes creator and default assignee to the \xAB\u0410\u0433\u0435\u043D\u0442 \u0418\u0418\xBB service user (UserKind.SERVICE) unless assigneeUserId is set. The AI orchestrator processes STORY items only when assignee is that service user. Priority defaults to LOW when omitted.",
|
|
6917
|
+
description: "Create a work item under a project. MCP/automation attributes creator and default assignee to the \xAB\u0410\u0433\u0435\u043D\u0442 \u0418\u0418\xBB service user (UserKind.SERVICE) unless assigneeUserId is set. The AI orchestrator processes STORY items only when assignee is that service user. Priority defaults to LOW when omitted. storyPoints and estimate are optional on create; when project.estimationRequired is true they are required before moving a STORY to any column except backlog (slug=backlog).",
|
|
6188
6918
|
inputSchema: {
|
|
6189
6919
|
projectId: z11.string().uuid().describe("Project UUID"),
|
|
6190
6920
|
type: z11.enum(workItemTypeValues).describe("Work item type"),
|
|
@@ -6193,9 +6923,11 @@ function registerWorkItemTools(server, client) {
|
|
|
6193
6923
|
description: z11.string().nullable().optional().describe("Work item description"),
|
|
6194
6924
|
acceptanceCriteria: z11.string().nullable().optional().describe("Acceptance criteria"),
|
|
6195
6925
|
priority: z11.enum(priorityValues).nullable().optional().describe("Work item priority; defaults to LOW when omitted or null"),
|
|
6196
|
-
storyPoints: z11.number().int().min(0).max(999).nullable().optional().describe(
|
|
6926
|
+
storyPoints: z11.number().int().min(0).max(999).nullable().optional().describe(
|
|
6927
|
+
"Story points (EPIC/STORY only). Optional on create; required before move to non-backlog columns when project estimationRequired and mode is storyPoints"
|
|
6928
|
+
),
|
|
6197
6929
|
estimate: z11.string().nullable().optional().describe(
|
|
6198
|
-
"Estimate in hours as decimal string (EPIC/STORY only).
|
|
6930
|
+
"Estimate in hours as decimal string (EPIC/STORY only). Optional on create; required before move to non-backlog columns when estimationRequired and mode is estimate"
|
|
6199
6931
|
),
|
|
6200
6932
|
assigneeUserId: z11.string().uuid().nullable().optional().describe(
|
|
6201
6933
|
"Project member user id; defaults to creator (human) or \xAB\u0410\u0433\u0435\u043D\u0442 \u0418\u0418\xBB service user (MCP) when omitted"
|
|
@@ -6234,7 +6966,7 @@ function registerWorkItemTools(server, client) {
|
|
|
6234
6966
|
server.registerTool(
|
|
6235
6967
|
"update_work_item",
|
|
6236
6968
|
{
|
|
6237
|
-
description: "Update work item fields (fetches current version first).",
|
|
6969
|
+
description: "Update work item fields (fetches current version first). On stale version returns AGENT_VERSION_STALE with fieldConflicts \u2014 no automatic retry; re-fetch get_work_item and reconcile manually.",
|
|
6238
6970
|
inputSchema: {
|
|
6239
6971
|
workItemId: z11.string().uuid().describe("Work item UUID"),
|
|
6240
6972
|
title: z11.string().min(1).max(512).optional().describe("Updated title"),
|
|
@@ -6267,9 +6999,8 @@ function registerWorkItemTools(server, client) {
|
|
|
6267
6999
|
codeChangesRequired,
|
|
6268
7000
|
completed,
|
|
6269
7001
|
labelIds
|
|
6270
|
-
}) => runTool(
|
|
6271
|
-
|
|
6272
|
-
const body = {
|
|
7002
|
+
}) => runTool(
|
|
7003
|
+
async () => patchWorkItemWithCurrentVersion(client, workItemId, {
|
|
6273
7004
|
title,
|
|
6274
7005
|
description,
|
|
6275
7006
|
acceptanceCriteria,
|
|
@@ -6281,16 +7012,14 @@ function registerWorkItemTools(server, client) {
|
|
|
6281
7012
|
assigneeUserId,
|
|
6282
7013
|
codeChangesRequired,
|
|
6283
7014
|
completed,
|
|
6284
|
-
labelIds
|
|
6285
|
-
|
|
6286
|
-
|
|
6287
|
-
return client.patch(import_work_items.WORK_ITEMS_ROUTES.updateWorkItem(workItemId), body);
|
|
6288
|
-
})
|
|
7015
|
+
labelIds
|
|
7016
|
+
})
|
|
7017
|
+
)
|
|
6289
7018
|
);
|
|
6290
7019
|
server.registerTool(
|
|
6291
7020
|
"move_work_item",
|
|
6292
7021
|
{
|
|
6293
|
-
description: "Move a work item to another board column (fetches current version first).",
|
|
7022
|
+
description: "Move a work item to another board column (fetches current version first). When project.estimationRequired is true, returns ESTIMATION_REQUIRED_FOR_MOVE (422) if the STORY lacks active storyPoints or estimate (per estimationMode) and the target column slug is not backlog.",
|
|
6294
7023
|
inputSchema: {
|
|
6295
7024
|
workItemId: z11.string().uuid().describe("Work item UUID"),
|
|
6296
7025
|
columnId: z11.string().uuid().describe("Target column UUID")
|
|
@@ -6364,12 +7093,20 @@ async function main() {
|
|
|
6364
7093
|
// src/cli.ts
|
|
6365
7094
|
async function main2() {
|
|
6366
7095
|
const argv = process.argv.slice(2);
|
|
7096
|
+
if (isHelpInvocation(argv)) {
|
|
7097
|
+
process.stdout.write(formatCliHelp({ packageMeta: readPackageMeta() }));
|
|
7098
|
+
process.exit(0);
|
|
7099
|
+
}
|
|
6367
7100
|
if (isAttentionCliInvocation(argv)) {
|
|
6368
7101
|
const config = loadConfig();
|
|
6369
7102
|
const client = new RestClient(config.apiUrl, config.apiToken);
|
|
6370
7103
|
const exitCode = await runAttentionCli(argv, { config, client });
|
|
6371
7104
|
process.exit(exitCode);
|
|
6372
7105
|
}
|
|
7106
|
+
if (isSkillsCliInvocation(argv)) {
|
|
7107
|
+
const exitCode = runSkillsCli(argv);
|
|
7108
|
+
process.exit(exitCode);
|
|
7109
|
+
}
|
|
6373
7110
|
await main();
|
|
6374
7111
|
}
|
|
6375
7112
|
main2().catch((error) => {
|