@vibescope/mcp-server 0.2.0 → 0.2.2
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 +60 -7
- package/dist/api-client.d.ts +251 -1
- package/dist/api-client.js +82 -3
- package/dist/handlers/blockers.js +9 -8
- package/dist/handlers/bodies-of-work.js +96 -63
- package/dist/handlers/connectors.d.ts +45 -0
- package/dist/handlers/connectors.js +183 -0
- package/dist/handlers/cost.d.ts +10 -0
- package/dist/handlers/cost.js +112 -50
- package/dist/handlers/decisions.js +32 -19
- package/dist/handlers/deployment.js +144 -122
- package/dist/handlers/discovery.d.ts +7 -0
- package/dist/handlers/discovery.js +96 -7
- package/dist/handlers/fallback.js +29 -23
- package/dist/handlers/file-checkouts.d.ts +20 -0
- package/dist/handlers/file-checkouts.js +133 -0
- package/dist/handlers/findings.d.ts +6 -0
- package/dist/handlers/findings.js +96 -40
- package/dist/handlers/git-issues.js +40 -36
- package/dist/handlers/ideas.js +49 -31
- package/dist/handlers/index.d.ts +3 -0
- package/dist/handlers/index.js +9 -0
- package/dist/handlers/milestones.js +39 -32
- package/dist/handlers/organizations.js +99 -91
- package/dist/handlers/progress.js +24 -13
- package/dist/handlers/project.js +68 -28
- package/dist/handlers/requests.js +18 -14
- package/dist/handlers/roles.d.ts +18 -0
- package/dist/handlers/roles.js +130 -0
- package/dist/handlers/session.js +58 -17
- package/dist/handlers/sprints.js +93 -81
- package/dist/handlers/tasks.d.ts +2 -0
- package/dist/handlers/tasks.js +189 -91
- package/dist/handlers/types.d.ts +64 -2
- package/dist/handlers/types.js +48 -1
- package/dist/handlers/validation.js +21 -17
- package/dist/index.js +7 -2716
- package/dist/token-tracking.d.ts +74 -0
- package/dist/token-tracking.js +122 -0
- package/dist/tools.js +685 -9
- package/dist/utils.d.ts +5 -0
- package/dist/utils.js +17 -0
- package/docs/TOOLS.md +2053 -0
- package/package.json +4 -1
- package/scripts/generate-docs.ts +212 -0
- package/src/api-client.test.ts +718 -0
- package/src/api-client.ts +320 -6
- package/src/handlers/__test-setup__.ts +16 -0
- package/src/handlers/blockers.test.ts +31 -19
- package/src/handlers/blockers.ts +9 -8
- package/src/handlers/bodies-of-work.test.ts +55 -32
- package/src/handlers/bodies-of-work.ts +115 -115
- package/src/handlers/connectors.test.ts +834 -0
- package/src/handlers/connectors.ts +229 -0
- package/src/handlers/cost.test.ts +34 -44
- package/src/handlers/cost.ts +136 -85
- package/src/handlers/decisions.test.ts +37 -27
- package/src/handlers/decisions.ts +35 -30
- package/src/handlers/deployment.ts +180 -208
- package/src/handlers/discovery.test.ts +4 -5
- package/src/handlers/discovery.ts +98 -8
- package/src/handlers/fallback.test.ts +26 -22
- package/src/handlers/fallback.ts +36 -33
- package/src/handlers/file-checkouts.test.ts +670 -0
- package/src/handlers/file-checkouts.ts +165 -0
- package/src/handlers/findings.test.ts +178 -19
- package/src/handlers/findings.ts +112 -74
- package/src/handlers/git-issues.test.ts +51 -43
- package/src/handlers/git-issues.ts +44 -84
- package/src/handlers/ideas.test.ts +28 -23
- package/src/handlers/ideas.ts +61 -59
- package/src/handlers/index.ts +9 -0
- package/src/handlers/milestones.test.ts +33 -28
- package/src/handlers/milestones.ts +52 -50
- package/src/handlers/organizations.test.ts +104 -83
- package/src/handlers/organizations.ts +117 -142
- package/src/handlers/progress.test.ts +20 -14
- package/src/handlers/progress.ts +26 -24
- package/src/handlers/project.test.ts +34 -27
- package/src/handlers/project.ts +95 -63
- package/src/handlers/requests.test.ts +27 -18
- package/src/handlers/requests.ts +21 -17
- package/src/handlers/roles.test.ts +303 -0
- package/src/handlers/roles.ts +208 -0
- package/src/handlers/session.test.ts +47 -0
- package/src/handlers/session.ts +71 -26
- package/src/handlers/sprints.test.ts +71 -50
- package/src/handlers/sprints.ts +113 -146
- package/src/handlers/tasks.test.ts +77 -15
- package/src/handlers/tasks.ts +231 -156
- package/src/handlers/tool-categories.test.ts +66 -0
- package/src/handlers/types.ts +81 -2
- package/src/handlers/validation.test.ts +78 -45
- package/src/handlers/validation.ts +23 -25
- package/src/index.ts +12 -2732
- package/src/token-tracking.test.ts +453 -0
- package/src/token-tracking.ts +164 -0
- package/src/tools.ts +685 -9
- package/src/utils.test.ts +2 -2
- package/src/utils.ts +17 -0
- package/dist/config/tool-categories.d.ts +0 -31
- package/dist/config/tool-categories.js +0 -253
- package/dist/knowledge.d.ts +0 -6
- package/dist/knowledge.js +0 -218
package/src/api-client.ts
CHANGED
|
@@ -47,7 +47,8 @@ export class VibescopeApiClient {
|
|
|
47
47
|
return {
|
|
48
48
|
ok: false,
|
|
49
49
|
status: response.status,
|
|
50
|
-
error: data.error || `HTTP ${response.status}
|
|
50
|
+
error: data.error || `HTTP ${response.status}`,
|
|
51
|
+
data // Include full response data for additional error context
|
|
51
52
|
};
|
|
52
53
|
}
|
|
53
54
|
|
|
@@ -122,6 +123,23 @@ export class VibescopeApiClient {
|
|
|
122
123
|
priority: number;
|
|
123
124
|
estimated_minutes?: number;
|
|
124
125
|
} | null;
|
|
126
|
+
pending_requests?: Array<{
|
|
127
|
+
id: string;
|
|
128
|
+
request_type: string;
|
|
129
|
+
message: string;
|
|
130
|
+
created_at: string;
|
|
131
|
+
}>;
|
|
132
|
+
pending_requests_count?: number;
|
|
133
|
+
URGENT_QUESTIONS?: {
|
|
134
|
+
count: number;
|
|
135
|
+
oldest_waiting_minutes: number;
|
|
136
|
+
action_required: string;
|
|
137
|
+
requests: Array<{
|
|
138
|
+
id: string;
|
|
139
|
+
message: string;
|
|
140
|
+
waiting_minutes: number;
|
|
141
|
+
}>;
|
|
142
|
+
};
|
|
125
143
|
directive?: string;
|
|
126
144
|
blockers_count?: number;
|
|
127
145
|
validation_count?: number;
|
|
@@ -306,6 +324,7 @@ export class VibescopeApiClient {
|
|
|
306
324
|
estimated_minutes?: number;
|
|
307
325
|
blocking?: boolean;
|
|
308
326
|
session_id?: string;
|
|
327
|
+
task_type?: string;
|
|
309
328
|
}): Promise<ApiResponse<{
|
|
310
329
|
success: boolean;
|
|
311
330
|
task_id: string;
|
|
@@ -380,6 +399,7 @@ export class VibescopeApiClient {
|
|
|
380
399
|
progress_note?: string;
|
|
381
400
|
estimated_minutes?: number;
|
|
382
401
|
git_branch?: string;
|
|
402
|
+
worktree_path?: string;
|
|
383
403
|
session_id?: string;
|
|
384
404
|
}): Promise<ApiResponse<{
|
|
385
405
|
success: boolean;
|
|
@@ -539,7 +559,11 @@ export class VibescopeApiClient {
|
|
|
539
559
|
// ============================================================================
|
|
540
560
|
// Decision endpoints
|
|
541
561
|
// ============================================================================
|
|
542
|
-
async getDecisions(projectId: string
|
|
562
|
+
async getDecisions(projectId: string, options?: {
|
|
563
|
+
limit?: number;
|
|
564
|
+
offset?: number;
|
|
565
|
+
search_query?: string;
|
|
566
|
+
}): Promise<ApiResponse<{
|
|
543
567
|
decisions: Array<{
|
|
544
568
|
id: string;
|
|
545
569
|
title: string;
|
|
@@ -549,7 +573,7 @@ export class VibescopeApiClient {
|
|
|
549
573
|
created_at: string;
|
|
550
574
|
}>;
|
|
551
575
|
}>> {
|
|
552
|
-
return this.proxy('get_decisions', { project_id: projectId });
|
|
576
|
+
return this.proxy('get_decisions', { project_id: projectId, ...options });
|
|
553
577
|
}
|
|
554
578
|
|
|
555
579
|
async logDecision(projectId: string, params: {
|
|
@@ -1005,6 +1029,8 @@ export class VibescopeApiClient {
|
|
|
1005
1029
|
async getActivityFeed(projectId: string, params?: {
|
|
1006
1030
|
limit?: number;
|
|
1007
1031
|
since?: string;
|
|
1032
|
+
types?: string[];
|
|
1033
|
+
created_by?: string;
|
|
1008
1034
|
}): Promise<ApiResponse<{
|
|
1009
1035
|
activities: Array<{
|
|
1010
1036
|
type: string;
|
|
@@ -1139,14 +1165,17 @@ export class VibescopeApiClient {
|
|
|
1139
1165
|
// Knowledge base endpoint
|
|
1140
1166
|
// ============================================================================
|
|
1141
1167
|
async queryKnowledgeBase(projectId: string, params?: {
|
|
1168
|
+
scope?: 'summary' | 'detailed';
|
|
1142
1169
|
categories?: string[];
|
|
1143
1170
|
limit?: number;
|
|
1144
1171
|
search_query?: string;
|
|
1145
1172
|
}): Promise<ApiResponse<{
|
|
1146
|
-
findings?: Array<{ id: string; title: string; category: string; severity: string }>;
|
|
1147
|
-
decisions?: Array<{ id: string; title: string; description: string }>;
|
|
1148
|
-
completed_tasks?: Array<{ id: string; title: string; completed_at: string }>;
|
|
1173
|
+
findings?: Array<{ id: string; title: string; category: string; severity: string; description?: string }>;
|
|
1174
|
+
decisions?: Array<{ id: string; title: string; description: string; rationale?: string }>;
|
|
1175
|
+
completed_tasks?: Array<{ id: string; title: string; completed_at: string; summary?: string }>;
|
|
1149
1176
|
resolved_blockers?: Array<{ id: string; description: string; resolution_note?: string }>;
|
|
1177
|
+
progress?: Array<{ id: string; summary: string; details?: string }>;
|
|
1178
|
+
qa?: Array<{ id: string; question: string; answer: string }>;
|
|
1150
1179
|
}>> {
|
|
1151
1180
|
return this.proxy('query_knowledge_base', {
|
|
1152
1181
|
project_id: projectId,
|
|
@@ -1598,6 +1627,63 @@ export class VibescopeApiClient {
|
|
|
1598
1627
|
});
|
|
1599
1628
|
}
|
|
1600
1629
|
|
|
1630
|
+
async getBodyOfWorkCosts(params: {
|
|
1631
|
+
body_of_work_id?: string;
|
|
1632
|
+
project_id?: string;
|
|
1633
|
+
}): Promise<ApiResponse<{
|
|
1634
|
+
bodies_of_work: Array<{
|
|
1635
|
+
body_of_work_id: string;
|
|
1636
|
+
title: string;
|
|
1637
|
+
project_id: string;
|
|
1638
|
+
status: string;
|
|
1639
|
+
task_count: number;
|
|
1640
|
+
total_cost_usd: number;
|
|
1641
|
+
total_tokens: number;
|
|
1642
|
+
pre_phase_cost_usd: number;
|
|
1643
|
+
core_phase_cost_usd: number;
|
|
1644
|
+
post_phase_cost_usd: number;
|
|
1645
|
+
model_breakdown: Record<string, { input: number; output: number }>;
|
|
1646
|
+
}>;
|
|
1647
|
+
count: number;
|
|
1648
|
+
totals: {
|
|
1649
|
+
total_cost_usd: number;
|
|
1650
|
+
total_tokens: number;
|
|
1651
|
+
total_tasks: number;
|
|
1652
|
+
};
|
|
1653
|
+
}>> {
|
|
1654
|
+
return this.proxy('get_body_of_work_costs', params);
|
|
1655
|
+
}
|
|
1656
|
+
|
|
1657
|
+
async getSprintCosts(params: {
|
|
1658
|
+
sprint_id?: string;
|
|
1659
|
+
project_id?: string;
|
|
1660
|
+
}): Promise<ApiResponse<{
|
|
1661
|
+
sprints: Array<{
|
|
1662
|
+
sprint_id: string;
|
|
1663
|
+
title: string;
|
|
1664
|
+
project_id: string;
|
|
1665
|
+
status: string;
|
|
1666
|
+
sprint_number: number;
|
|
1667
|
+
task_count: number;
|
|
1668
|
+
total_cost_usd: number;
|
|
1669
|
+
total_tokens: number;
|
|
1670
|
+
cost_per_story_point: number | null;
|
|
1671
|
+
committed_points: number;
|
|
1672
|
+
velocity_points: number;
|
|
1673
|
+
model_breakdown: Record<string, { input: number; output: number }>;
|
|
1674
|
+
}>;
|
|
1675
|
+
count: number;
|
|
1676
|
+
totals: {
|
|
1677
|
+
total_cost_usd: number;
|
|
1678
|
+
total_tokens: number;
|
|
1679
|
+
total_tasks: number;
|
|
1680
|
+
total_velocity_points: number;
|
|
1681
|
+
avg_cost_per_point: number | null;
|
|
1682
|
+
};
|
|
1683
|
+
}>> {
|
|
1684
|
+
return this.proxy('get_sprint_costs', params);
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1601
1687
|
async getTokenUsage(): Promise<ApiResponse<{
|
|
1602
1688
|
session_tokens: number;
|
|
1603
1689
|
estimated_cost: number;
|
|
@@ -1684,6 +1770,7 @@ export class VibescopeApiClient {
|
|
|
1684
1770
|
environment?: string;
|
|
1685
1771
|
version_bump?: string;
|
|
1686
1772
|
auto_trigger?: boolean;
|
|
1773
|
+
hours_interval?: number;
|
|
1687
1774
|
notes?: string;
|
|
1688
1775
|
git_ref?: string;
|
|
1689
1776
|
}): Promise<ApiResponse<{
|
|
@@ -1701,6 +1788,7 @@ export class VibescopeApiClient {
|
|
|
1701
1788
|
id: string;
|
|
1702
1789
|
scheduled_at: string;
|
|
1703
1790
|
schedule_type: string;
|
|
1791
|
+
hours_interval: number;
|
|
1704
1792
|
environment: string;
|
|
1705
1793
|
version_bump: string;
|
|
1706
1794
|
auto_trigger: boolean;
|
|
@@ -1720,6 +1808,7 @@ export class VibescopeApiClient {
|
|
|
1720
1808
|
async updateScheduledDeployment(scheduleId: string, updates: {
|
|
1721
1809
|
scheduled_at?: string;
|
|
1722
1810
|
schedule_type?: string;
|
|
1811
|
+
hours_interval?: number;
|
|
1723
1812
|
environment?: string;
|
|
1724
1813
|
version_bump?: string;
|
|
1725
1814
|
auto_trigger?: boolean;
|
|
@@ -1800,6 +1889,231 @@ export class VibescopeApiClient {
|
|
|
1800
1889
|
}>>> {
|
|
1801
1890
|
return this.proxy('get_help_topics', {});
|
|
1802
1891
|
}
|
|
1892
|
+
|
|
1893
|
+
// ============================================================================
|
|
1894
|
+
// File Checkout endpoints (multi-agent coordination)
|
|
1895
|
+
// ============================================================================
|
|
1896
|
+
async checkoutFile(projectId: string, filePath: string, reason?: string, sessionId?: string): Promise<ApiResponse<{
|
|
1897
|
+
success: boolean;
|
|
1898
|
+
checkout_id: string;
|
|
1899
|
+
file_path: string;
|
|
1900
|
+
already_checked_out?: boolean;
|
|
1901
|
+
message: string;
|
|
1902
|
+
}>> {
|
|
1903
|
+
return this.proxy('checkout_file', {
|
|
1904
|
+
project_id: projectId,
|
|
1905
|
+
file_path: filePath,
|
|
1906
|
+
reason
|
|
1907
|
+
}, sessionId ? {
|
|
1908
|
+
session_id: sessionId,
|
|
1909
|
+
persona: null,
|
|
1910
|
+
instance_id: ''
|
|
1911
|
+
} : undefined);
|
|
1912
|
+
}
|
|
1913
|
+
|
|
1914
|
+
async checkinFile(params: {
|
|
1915
|
+
checkout_id?: string;
|
|
1916
|
+
project_id?: string;
|
|
1917
|
+
file_path?: string;
|
|
1918
|
+
summary?: string;
|
|
1919
|
+
}, sessionId?: string): Promise<ApiResponse<{
|
|
1920
|
+
success: boolean;
|
|
1921
|
+
checkout_id: string;
|
|
1922
|
+
message: string;
|
|
1923
|
+
}>> {
|
|
1924
|
+
return this.proxy('checkin_file', params, sessionId ? {
|
|
1925
|
+
session_id: sessionId,
|
|
1926
|
+
persona: null,
|
|
1927
|
+
instance_id: ''
|
|
1928
|
+
} : undefined);
|
|
1929
|
+
}
|
|
1930
|
+
|
|
1931
|
+
async getFileCheckouts(projectId: string, options?: {
|
|
1932
|
+
status?: string;
|
|
1933
|
+
file_path?: string;
|
|
1934
|
+
limit?: number;
|
|
1935
|
+
}): Promise<ApiResponse<{
|
|
1936
|
+
checkouts: Array<{
|
|
1937
|
+
id: string;
|
|
1938
|
+
file_path: string;
|
|
1939
|
+
status: string;
|
|
1940
|
+
checked_out_at: string;
|
|
1941
|
+
checkout_reason?: string;
|
|
1942
|
+
checked_in_at?: string;
|
|
1943
|
+
checkin_summary?: string;
|
|
1944
|
+
checked_out_by?: string;
|
|
1945
|
+
}>;
|
|
1946
|
+
}>> {
|
|
1947
|
+
return this.proxy('get_file_checkouts', {
|
|
1948
|
+
project_id: projectId,
|
|
1949
|
+
...options
|
|
1950
|
+
});
|
|
1951
|
+
}
|
|
1952
|
+
|
|
1953
|
+
async abandonCheckout(params: {
|
|
1954
|
+
checkout_id?: string;
|
|
1955
|
+
project_id?: string;
|
|
1956
|
+
file_path?: string;
|
|
1957
|
+
}): Promise<ApiResponse<{
|
|
1958
|
+
success: boolean;
|
|
1959
|
+
checkout_id: string;
|
|
1960
|
+
message: string;
|
|
1961
|
+
}>> {
|
|
1962
|
+
return this.proxy('abandon_checkout', params);
|
|
1963
|
+
}
|
|
1964
|
+
|
|
1965
|
+
// ============================================================================
|
|
1966
|
+
// Worktree Management
|
|
1967
|
+
// ============================================================================
|
|
1968
|
+
|
|
1969
|
+
async getStaleWorktrees(projectId: string): Promise<ApiResponse<{
|
|
1970
|
+
project_id: string;
|
|
1971
|
+
project_name: string;
|
|
1972
|
+
stale_worktrees: Array<{
|
|
1973
|
+
task_id: string;
|
|
1974
|
+
task_title: string;
|
|
1975
|
+
worktree_path: string;
|
|
1976
|
+
git_branch: string | null;
|
|
1977
|
+
status: string;
|
|
1978
|
+
completed_at: string | null;
|
|
1979
|
+
updated_at: string;
|
|
1980
|
+
pr_url: string | null;
|
|
1981
|
+
stale_reason: 'task_finished' | 'potentially_abandoned';
|
|
1982
|
+
}>;
|
|
1983
|
+
count: number;
|
|
1984
|
+
cleanup_instructions: string[] | null;
|
|
1985
|
+
}>> {
|
|
1986
|
+
return this.request('GET', `/api/mcp/worktrees/stale?project_id=${projectId}`);
|
|
1987
|
+
}
|
|
1988
|
+
|
|
1989
|
+
async clearWorktreePath(taskId: string): Promise<ApiResponse<{
|
|
1990
|
+
success: boolean;
|
|
1991
|
+
task_id: string;
|
|
1992
|
+
}>> {
|
|
1993
|
+
return this.request('PATCH', `/api/mcp/tasks/${taskId}`, { worktree_path: null });
|
|
1994
|
+
}
|
|
1995
|
+
|
|
1996
|
+
// ============================================================================
|
|
1997
|
+
// Connector endpoints
|
|
1998
|
+
// ============================================================================
|
|
1999
|
+
|
|
2000
|
+
async getConnectors(projectId: string, params?: {
|
|
2001
|
+
type?: string;
|
|
2002
|
+
status?: string;
|
|
2003
|
+
limit?: number;
|
|
2004
|
+
offset?: number;
|
|
2005
|
+
}): Promise<ApiResponse<{
|
|
2006
|
+
connectors: Array<{
|
|
2007
|
+
id: string;
|
|
2008
|
+
name: string;
|
|
2009
|
+
type: string;
|
|
2010
|
+
description?: string;
|
|
2011
|
+
status: string;
|
|
2012
|
+
events: Record<string, boolean>;
|
|
2013
|
+
events_sent: number;
|
|
2014
|
+
last_triggered_at?: string;
|
|
2015
|
+
last_error?: string;
|
|
2016
|
+
last_error_at?: string;
|
|
2017
|
+
created_at: string;
|
|
2018
|
+
}>;
|
|
2019
|
+
total_count: number;
|
|
2020
|
+
has_more: boolean;
|
|
2021
|
+
}>> {
|
|
2022
|
+
return this.proxy('get_connectors', {
|
|
2023
|
+
project_id: projectId,
|
|
2024
|
+
...params
|
|
2025
|
+
});
|
|
2026
|
+
}
|
|
2027
|
+
|
|
2028
|
+
async getConnector(connectorId: string): Promise<ApiResponse<{
|
|
2029
|
+
connector: {
|
|
2030
|
+
id: string;
|
|
2031
|
+
name: string;
|
|
2032
|
+
type: string;
|
|
2033
|
+
description?: string;
|
|
2034
|
+
config: Record<string, unknown>;
|
|
2035
|
+
events: Record<string, boolean>;
|
|
2036
|
+
status: string;
|
|
2037
|
+
events_sent: number;
|
|
2038
|
+
last_triggered_at?: string;
|
|
2039
|
+
last_error?: string;
|
|
2040
|
+
last_error_at?: string;
|
|
2041
|
+
created_at: string;
|
|
2042
|
+
};
|
|
2043
|
+
}>> {
|
|
2044
|
+
return this.proxy('get_connector', { connector_id: connectorId });
|
|
2045
|
+
}
|
|
2046
|
+
|
|
2047
|
+
async addConnector(projectId: string, params: {
|
|
2048
|
+
name: string;
|
|
2049
|
+
type: string;
|
|
2050
|
+
description?: string;
|
|
2051
|
+
config?: Record<string, unknown>;
|
|
2052
|
+
events?: Record<string, boolean>;
|
|
2053
|
+
}): Promise<ApiResponse<{
|
|
2054
|
+
success: boolean;
|
|
2055
|
+
connector_id: string;
|
|
2056
|
+
}>> {
|
|
2057
|
+
return this.proxy('add_connector', {
|
|
2058
|
+
project_id: projectId,
|
|
2059
|
+
...params
|
|
2060
|
+
});
|
|
2061
|
+
}
|
|
2062
|
+
|
|
2063
|
+
async updateConnector(connectorId: string, updates: {
|
|
2064
|
+
name?: string;
|
|
2065
|
+
description?: string;
|
|
2066
|
+
config?: Record<string, unknown>;
|
|
2067
|
+
events?: Record<string, boolean>;
|
|
2068
|
+
status?: string;
|
|
2069
|
+
}): Promise<ApiResponse<{
|
|
2070
|
+
success: boolean;
|
|
2071
|
+
connector_id: string;
|
|
2072
|
+
}>> {
|
|
2073
|
+
return this.proxy('update_connector', {
|
|
2074
|
+
connector_id: connectorId,
|
|
2075
|
+
...updates
|
|
2076
|
+
});
|
|
2077
|
+
}
|
|
2078
|
+
|
|
2079
|
+
async deleteConnector(connectorId: string): Promise<ApiResponse<{
|
|
2080
|
+
success: boolean;
|
|
2081
|
+
}>> {
|
|
2082
|
+
return this.proxy('delete_connector', { connector_id: connectorId });
|
|
2083
|
+
}
|
|
2084
|
+
|
|
2085
|
+
async testConnector(connectorId: string): Promise<ApiResponse<{
|
|
2086
|
+
success: boolean;
|
|
2087
|
+
event_id: string;
|
|
2088
|
+
status?: number;
|
|
2089
|
+
error?: string;
|
|
2090
|
+
}>> {
|
|
2091
|
+
return this.proxy('test_connector', { connector_id: connectorId });
|
|
2092
|
+
}
|
|
2093
|
+
|
|
2094
|
+
async getConnectorEvents(params: {
|
|
2095
|
+
connector_id?: string;
|
|
2096
|
+
project_id?: string;
|
|
2097
|
+
status?: string;
|
|
2098
|
+
limit?: number;
|
|
2099
|
+
offset?: number;
|
|
2100
|
+
}): Promise<ApiResponse<{
|
|
2101
|
+
events: Array<{
|
|
2102
|
+
id: string;
|
|
2103
|
+
connector_id: string;
|
|
2104
|
+
event_type: string;
|
|
2105
|
+
status: string;
|
|
2106
|
+
response_status?: number;
|
|
2107
|
+
error_message?: string;
|
|
2108
|
+
attempts: number;
|
|
2109
|
+
created_at: string;
|
|
2110
|
+
sent_at?: string;
|
|
2111
|
+
}>;
|
|
2112
|
+
total_count: number;
|
|
2113
|
+
has_more: boolean;
|
|
2114
|
+
}>> {
|
|
2115
|
+
return this.proxy('get_connector_events', params);
|
|
2116
|
+
}
|
|
1803
2117
|
}
|
|
1804
2118
|
|
|
1805
2119
|
// Singleton instance
|
|
@@ -80,6 +80,7 @@ export const mockApiClient = {
|
|
|
80
80
|
getFindingsStats: vi.fn(),
|
|
81
81
|
updateFinding: vi.fn(),
|
|
82
82
|
deleteFinding: vi.fn(),
|
|
83
|
+
queryKnowledgeBase: vi.fn(),
|
|
83
84
|
|
|
84
85
|
// Requests
|
|
85
86
|
getPendingRequests: vi.fn(),
|
|
@@ -169,6 +170,21 @@ export const mockApiClient = {
|
|
|
169
170
|
getHelpTopic: vi.fn(),
|
|
170
171
|
getHelpTopics: vi.fn(),
|
|
171
172
|
|
|
173
|
+
// File Checkouts
|
|
174
|
+
checkoutFile: vi.fn(),
|
|
175
|
+
checkinFile: vi.fn(),
|
|
176
|
+
getFileCheckouts: vi.fn(),
|
|
177
|
+
abandonCheckout: vi.fn(),
|
|
178
|
+
|
|
179
|
+
// Connectors
|
|
180
|
+
getConnectors: vi.fn(),
|
|
181
|
+
getConnector: vi.fn(),
|
|
182
|
+
addConnector: vi.fn(),
|
|
183
|
+
updateConnector: vi.fn(),
|
|
184
|
+
deleteConnector: vi.fn(),
|
|
185
|
+
testConnector: vi.fn(),
|
|
186
|
+
getConnectorEvents: vi.fn(),
|
|
187
|
+
|
|
172
188
|
// Proxy (generic)
|
|
173
189
|
proxy: vi.fn(),
|
|
174
190
|
};
|
|
@@ -83,19 +83,22 @@ describe('addBlocker', () => {
|
|
|
83
83
|
);
|
|
84
84
|
});
|
|
85
85
|
|
|
86
|
-
it('should
|
|
86
|
+
it('should return error when API call fails', async () => {
|
|
87
87
|
mockApiClient.addBlocker.mockResolvedValue({
|
|
88
88
|
ok: false,
|
|
89
89
|
error: 'Insert failed',
|
|
90
90
|
});
|
|
91
91
|
const ctx = createMockContext();
|
|
92
92
|
|
|
93
|
-
await
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
).
|
|
93
|
+
const result = await addBlocker({
|
|
94
|
+
project_id: '123e4567-e89b-12d3-a456-426614174000',
|
|
95
|
+
description: 'Test blocker',
|
|
96
|
+
}, ctx);
|
|
97
|
+
|
|
98
|
+
expect(result.isError).toBe(true);
|
|
99
|
+
expect(result.result).toMatchObject({
|
|
100
|
+
error: 'Insert failed',
|
|
101
|
+
});
|
|
99
102
|
});
|
|
100
103
|
});
|
|
101
104
|
|
|
@@ -177,16 +180,19 @@ describe('resolveBlocker', () => {
|
|
|
177
180
|
);
|
|
178
181
|
});
|
|
179
182
|
|
|
180
|
-
it('should
|
|
183
|
+
it('should return error when API call fails', async () => {
|
|
181
184
|
mockApiClient.resolveBlocker.mockResolvedValue({
|
|
182
185
|
ok: false,
|
|
183
186
|
error: 'Update failed',
|
|
184
187
|
});
|
|
185
188
|
const ctx = createMockContext();
|
|
186
189
|
|
|
187
|
-
await
|
|
188
|
-
|
|
189
|
-
).
|
|
190
|
+
const result = await resolveBlocker({ blocker_id: '123e4567-e89b-12d3-a456-426614174000' }, ctx);
|
|
191
|
+
|
|
192
|
+
expect(result.isError).toBe(true);
|
|
193
|
+
expect(result.result).toMatchObject({
|
|
194
|
+
error: 'Update failed',
|
|
195
|
+
});
|
|
190
196
|
});
|
|
191
197
|
});
|
|
192
198
|
|
|
@@ -298,16 +304,19 @@ describe('getBlockers', () => {
|
|
|
298
304
|
expect(mockApiClient.getBlockers).toHaveBeenCalled();
|
|
299
305
|
});
|
|
300
306
|
|
|
301
|
-
it('should
|
|
307
|
+
it('should return error when API call fails', async () => {
|
|
302
308
|
mockApiClient.getBlockers.mockResolvedValue({
|
|
303
309
|
ok: false,
|
|
304
310
|
error: 'Query failed',
|
|
305
311
|
});
|
|
306
312
|
const ctx = createMockContext();
|
|
307
313
|
|
|
308
|
-
await
|
|
309
|
-
|
|
310
|
-
).
|
|
314
|
+
const result = await getBlockers({ project_id: '123e4567-e89b-12d3-a456-426614174000' }, ctx);
|
|
315
|
+
|
|
316
|
+
expect(result.isError).toBe(true);
|
|
317
|
+
expect(result.result).toMatchObject({
|
|
318
|
+
error: 'Query failed',
|
|
319
|
+
});
|
|
311
320
|
});
|
|
312
321
|
});
|
|
313
322
|
|
|
@@ -366,15 +375,18 @@ describe('deleteBlocker', () => {
|
|
|
366
375
|
);
|
|
367
376
|
});
|
|
368
377
|
|
|
369
|
-
it('should
|
|
378
|
+
it('should return error when API call fails', async () => {
|
|
370
379
|
mockApiClient.deleteBlocker.mockResolvedValue({
|
|
371
380
|
ok: false,
|
|
372
381
|
error: 'Delete failed',
|
|
373
382
|
});
|
|
374
383
|
const ctx = createMockContext();
|
|
375
384
|
|
|
376
|
-
await
|
|
377
|
-
|
|
378
|
-
).
|
|
385
|
+
const result = await deleteBlocker({ blocker_id: '123e4567-e89b-12d3-a456-426614174000' }, ctx);
|
|
386
|
+
|
|
387
|
+
expect(result.isError).toBe(true);
|
|
388
|
+
expect(result.result).toMatchObject({
|
|
389
|
+
error: 'Delete failed',
|
|
390
|
+
});
|
|
379
391
|
});
|
|
380
392
|
});
|
package/src/handlers/blockers.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import type { Handler, HandlerRegistry } from './types.js';
|
|
12
|
+
import { success, error } from './types.js';
|
|
12
13
|
import {
|
|
13
14
|
parseArgs,
|
|
14
15
|
uuidValidator,
|
|
@@ -47,10 +48,10 @@ export const addBlocker: Handler = async (args, ctx) => {
|
|
|
47
48
|
const response = await apiClient.addBlocker(project_id, description, ctx.session.currentSessionId || undefined);
|
|
48
49
|
|
|
49
50
|
if (!response.ok) {
|
|
50
|
-
|
|
51
|
+
return error(response.error || 'Failed to add blocker');
|
|
51
52
|
}
|
|
52
53
|
|
|
53
|
-
return
|
|
54
|
+
return success(response.data);
|
|
54
55
|
};
|
|
55
56
|
|
|
56
57
|
export const resolveBlocker: Handler = async (args, _ctx) => {
|
|
@@ -60,10 +61,10 @@ export const resolveBlocker: Handler = async (args, _ctx) => {
|
|
|
60
61
|
const response = await apiClient.resolveBlocker(blocker_id, resolution_note);
|
|
61
62
|
|
|
62
63
|
if (!response.ok) {
|
|
63
|
-
|
|
64
|
+
return error(response.error || 'Failed to resolve blocker');
|
|
64
65
|
}
|
|
65
66
|
|
|
66
|
-
return
|
|
67
|
+
return success(response.data);
|
|
67
68
|
};
|
|
68
69
|
|
|
69
70
|
export const getBlockers: Handler = async (args, _ctx) => {
|
|
@@ -78,10 +79,10 @@ export const getBlockers: Handler = async (args, _ctx) => {
|
|
|
78
79
|
});
|
|
79
80
|
|
|
80
81
|
if (!response.ok) {
|
|
81
|
-
|
|
82
|
+
return error(response.error || 'Failed to fetch blockers');
|
|
82
83
|
}
|
|
83
84
|
|
|
84
|
-
return
|
|
85
|
+
return success(response.data);
|
|
85
86
|
};
|
|
86
87
|
|
|
87
88
|
export const deleteBlocker: Handler = async (args, _ctx) => {
|
|
@@ -91,10 +92,10 @@ export const deleteBlocker: Handler = async (args, _ctx) => {
|
|
|
91
92
|
const response = await apiClient.deleteBlocker(blocker_id);
|
|
92
93
|
|
|
93
94
|
if (!response.ok) {
|
|
94
|
-
|
|
95
|
+
return error(response.error || 'Failed to delete blocker');
|
|
95
96
|
}
|
|
96
97
|
|
|
97
|
-
return
|
|
98
|
+
return success(response.data);
|
|
98
99
|
};
|
|
99
100
|
|
|
100
101
|
/**
|