@vibescope/mcp-server 0.3.0 → 0.3.3

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.
Files changed (154) hide show
  1. package/dist/api-client/blockers.d.ts +46 -0
  2. package/dist/api-client/blockers.js +43 -0
  3. package/dist/api-client/cost.d.ts +112 -0
  4. package/dist/api-client/cost.js +76 -0
  5. package/dist/api-client/decisions.d.ts +55 -0
  6. package/dist/api-client/decisions.js +32 -0
  7. package/dist/api-client/discovery.d.ts +62 -0
  8. package/dist/api-client/discovery.js +21 -0
  9. package/dist/api-client/ideas.d.ts +75 -0
  10. package/dist/api-client/ideas.js +36 -0
  11. package/dist/api-client/index.d.ts +749 -0
  12. package/dist/api-client/index.js +291 -0
  13. package/dist/api-client/project.d.ts +132 -0
  14. package/dist/api-client/project.js +45 -0
  15. package/dist/api-client/session.d.ts +163 -0
  16. package/dist/api-client/session.js +52 -0
  17. package/dist/api-client/tasks.d.ts +328 -0
  18. package/dist/api-client/tasks.js +132 -0
  19. package/dist/api-client/types.d.ts +25 -0
  20. package/dist/api-client/types.js +4 -0
  21. package/dist/api-client/worktrees.d.ts +33 -0
  22. package/dist/api-client/worktrees.js +26 -0
  23. package/dist/api-client.d.ts +9 -0
  24. package/dist/api-client.js +104 -25
  25. package/dist/cli-init.d.ts +17 -0
  26. package/dist/cli-init.js +445 -0
  27. package/dist/cli.js +0 -0
  28. package/dist/handlers/cloud-agents.d.ts +21 -0
  29. package/dist/handlers/cloud-agents.js +91 -0
  30. package/dist/handlers/discovery.js +7 -0
  31. package/dist/handlers/index.d.ts +1 -0
  32. package/dist/handlers/index.js +3 -0
  33. package/dist/handlers/session.js +3 -1
  34. package/dist/handlers/tasks.js +10 -12
  35. package/dist/handlers/types.d.ts +2 -1
  36. package/dist/handlers/validation.js +5 -1
  37. package/dist/index.js +8 -3
  38. package/dist/token-tracking.js +2 -2
  39. package/dist/tools/blockers.d.ts +13 -0
  40. package/dist/tools/blockers.js +119 -0
  41. package/dist/tools/bodies-of-work.d.ts +19 -0
  42. package/dist/tools/bodies-of-work.js +280 -0
  43. package/dist/tools/cloud-agents.d.ts +9 -0
  44. package/dist/tools/cloud-agents.js +67 -0
  45. package/dist/tools/connectors.d.ts +14 -0
  46. package/dist/tools/connectors.js +188 -0
  47. package/dist/tools/cost.d.ts +11 -0
  48. package/dist/tools/cost.js +108 -0
  49. package/dist/tools/decisions.d.ts +12 -0
  50. package/dist/tools/decisions.js +108 -0
  51. package/dist/tools/deployment.d.ts +24 -0
  52. package/dist/tools/deployment.js +439 -0
  53. package/dist/tools/discovery.d.ts +10 -0
  54. package/dist/tools/discovery.js +73 -0
  55. package/dist/tools/fallback.d.ts +11 -0
  56. package/dist/tools/fallback.js +108 -0
  57. package/dist/tools/file-checkouts.d.ts +13 -0
  58. package/dist/tools/file-checkouts.js +141 -0
  59. package/dist/tools/findings.d.ts +13 -0
  60. package/dist/tools/findings.js +98 -0
  61. package/dist/tools/git-issues.d.ts +11 -0
  62. package/dist/tools/git-issues.js +127 -0
  63. package/dist/tools/ideas.d.ts +13 -0
  64. package/dist/tools/ideas.js +159 -0
  65. package/dist/tools/index.d.ts +71 -0
  66. package/dist/tools/index.js +98 -0
  67. package/dist/tools/milestones.d.ts +12 -0
  68. package/dist/tools/milestones.js +115 -0
  69. package/dist/tools/organizations.d.ts +17 -0
  70. package/dist/tools/organizations.js +221 -0
  71. package/dist/tools/progress.d.ts +9 -0
  72. package/dist/tools/progress.js +70 -0
  73. package/dist/tools/project.d.ts +13 -0
  74. package/dist/tools/project.js +199 -0
  75. package/dist/tools/requests.d.ts +10 -0
  76. package/dist/tools/requests.js +65 -0
  77. package/dist/tools/roles.d.ts +11 -0
  78. package/dist/tools/roles.js +109 -0
  79. package/dist/tools/session.d.ts +15 -0
  80. package/dist/tools/session.js +178 -0
  81. package/dist/tools/sprints.d.ts +18 -0
  82. package/dist/tools/sprints.js +295 -0
  83. package/dist/tools/tasks.d.ts +27 -0
  84. package/dist/tools/tasks.js +539 -0
  85. package/dist/tools/types.d.ts +7 -0
  86. package/dist/tools/types.js +6 -0
  87. package/dist/tools/validation.d.ts +10 -0
  88. package/dist/tools/validation.js +72 -0
  89. package/dist/tools/worktrees.d.ts +9 -0
  90. package/dist/tools/worktrees.js +63 -0
  91. package/dist/utils.d.ts +66 -0
  92. package/dist/utils.js +102 -0
  93. package/docs/TOOLS.md +55 -2
  94. package/package.json +5 -3
  95. package/scripts/generate-docs.ts +1 -1
  96. package/src/api-client/blockers.ts +86 -0
  97. package/src/api-client/cost.ts +185 -0
  98. package/src/api-client/decisions.ts +87 -0
  99. package/src/api-client/discovery.ts +81 -0
  100. package/src/api-client/ideas.ts +112 -0
  101. package/src/api-client/index.ts +378 -0
  102. package/src/api-client/project.ts +179 -0
  103. package/src/api-client/session.ts +220 -0
  104. package/src/api-client/tasks.ts +450 -0
  105. package/src/api-client/types.ts +32 -0
  106. package/src/api-client/worktrees.ts +53 -0
  107. package/src/api-client.test.ts +136 -9
  108. package/src/api-client.ts +125 -27
  109. package/src/cli-init.ts +504 -0
  110. package/src/handlers/__test-utils__.ts +2 -0
  111. package/src/handlers/cloud-agents.ts +138 -0
  112. package/src/handlers/discovery.ts +7 -0
  113. package/src/handlers/index.ts +3 -0
  114. package/src/handlers/session.ts +3 -1
  115. package/src/handlers/tasks.ts +10 -12
  116. package/src/handlers/tool-categories.test.ts +1 -1
  117. package/src/handlers/types.ts +2 -1
  118. package/src/handlers/validation.ts +6 -1
  119. package/src/index.test.ts +2 -2
  120. package/src/index.ts +8 -2
  121. package/src/token-tracking.ts +3 -2
  122. package/src/tools/blockers.ts +122 -0
  123. package/src/tools/bodies-of-work.ts +283 -0
  124. package/src/tools/cloud-agents.ts +70 -0
  125. package/src/tools/connectors.ts +191 -0
  126. package/src/tools/cost.ts +111 -0
  127. package/src/tools/decisions.ts +111 -0
  128. package/src/tools/deployment.ts +442 -0
  129. package/src/tools/discovery.ts +76 -0
  130. package/src/tools/fallback.ts +111 -0
  131. package/src/tools/file-checkouts.ts +145 -0
  132. package/src/tools/findings.ts +101 -0
  133. package/src/tools/git-issues.ts +130 -0
  134. package/src/tools/ideas.ts +162 -0
  135. package/src/tools/index.ts +131 -0
  136. package/src/tools/milestones.ts +118 -0
  137. package/src/tools/organizations.ts +224 -0
  138. package/src/tools/progress.ts +73 -0
  139. package/src/tools/project.ts +202 -0
  140. package/src/tools/requests.ts +68 -0
  141. package/src/tools/roles.ts +112 -0
  142. package/src/tools/session.ts +181 -0
  143. package/src/tools/sprints.ts +298 -0
  144. package/src/tools/tasks.ts +542 -0
  145. package/src/tools/tools.test.ts +222 -0
  146. package/src/tools/types.ts +9 -0
  147. package/src/tools/validation.ts +75 -0
  148. package/src/tools/worktrees.ts +66 -0
  149. package/src/tools.test.ts +1 -1
  150. package/src/utils.test.ts +229 -0
  151. package/src/utils.ts +117 -0
  152. package/dist/tools.d.ts +0 -2
  153. package/dist/tools.js +0 -3602
  154. package/src/tools.ts +0 -3607
@@ -0,0 +1,291 @@
1
+ /**
2
+ * Vibescope API Client
3
+ *
4
+ * HTTP client for communicating with the Vibescope API.
5
+ * All database operations are handled server-side through these endpoints.
6
+ *
7
+ * This module composes domain-specific API methods into a unified client.
8
+ */
9
+ import { createSessionMethods } from './session.js';
10
+ import { createProjectMethods } from './project.js';
11
+ import { createBlockersMethods } from './blockers.js';
12
+ import { createCostMethods } from './cost.js';
13
+ import { createWorktreesMethods } from './worktrees.js';
14
+ import { createDiscoveryMethods } from './discovery.js';
15
+ import { createDecisionsMethods } from './decisions.js';
16
+ import { createIdeasMethods } from './ideas.js';
17
+ import { createTasksMethods } from './tasks.js';
18
+ const DEFAULT_API_URL = 'https://vibescope.dev';
19
+ // Retry configuration defaults
20
+ const DEFAULT_RETRY_STATUS_CODES = [429, 503, 504];
21
+ const DEFAULT_MAX_RETRIES = 3;
22
+ const DEFAULT_BASE_DELAY_MS = 1000;
23
+ const DEFAULT_MAX_DELAY_MS = 30000;
24
+ /**
25
+ * Calculate delay for exponential backoff with jitter
26
+ */
27
+ function calculateBackoffDelay(attempt, baseDelayMs, maxDelayMs, retryAfter) {
28
+ if (retryAfter !== undefined && retryAfter > 0) {
29
+ return Math.min(retryAfter * 1000, maxDelayMs);
30
+ }
31
+ const exponentialDelay = baseDelayMs * Math.pow(2, attempt);
32
+ const jitter = Math.random() * 0.3 * exponentialDelay;
33
+ return Math.min(exponentialDelay + jitter, maxDelayMs);
34
+ }
35
+ /**
36
+ * Sleep for a specified duration
37
+ */
38
+ function sleep(ms) {
39
+ return new Promise(resolve => setTimeout(resolve, ms));
40
+ }
41
+ export class VibescopeApiClient {
42
+ apiKey;
43
+ baseUrl;
44
+ retryConfig;
45
+ // Domain method implementations
46
+ sessionMethods;
47
+ projectMethods;
48
+ blockersMethods;
49
+ costMethods;
50
+ worktreesMethods;
51
+ discoveryMethods;
52
+ decisionsMethods;
53
+ ideasMethods;
54
+ tasksMethods;
55
+ constructor(config) {
56
+ this.apiKey = config.apiKey;
57
+ this.baseUrl = config.baseUrl || process.env.VIBESCOPE_API_URL || DEFAULT_API_URL;
58
+ this.retryConfig = {
59
+ maxRetries: config.retry?.maxRetries ?? DEFAULT_MAX_RETRIES,
60
+ baseDelayMs: config.retry?.baseDelayMs ?? DEFAULT_BASE_DELAY_MS,
61
+ maxDelayMs: config.retry?.maxDelayMs ?? DEFAULT_MAX_DELAY_MS,
62
+ retryStatusCodes: config.retry?.retryStatusCodes ?? DEFAULT_RETRY_STATUS_CODES,
63
+ };
64
+ // Create bound request and proxy functions for domain modules
65
+ const request = this.request.bind(this);
66
+ const proxy = this.proxy.bind(this);
67
+ const getApiKey = () => this.apiKey;
68
+ // Initialize domain methods
69
+ this.sessionMethods = createSessionMethods(request, getApiKey);
70
+ this.projectMethods = createProjectMethods(request);
71
+ this.blockersMethods = createBlockersMethods(request);
72
+ this.costMethods = createCostMethods(request);
73
+ this.worktreesMethods = createWorktreesMethods(request);
74
+ this.discoveryMethods = createDiscoveryMethods(request);
75
+ this.decisionsMethods = createDecisionsMethods(proxy);
76
+ this.ideasMethods = createIdeasMethods(proxy);
77
+ this.tasksMethods = createTasksMethods(request, proxy);
78
+ }
79
+ async request(method, path, body) {
80
+ const url = `${this.baseUrl}${path}`;
81
+ const { maxRetries, baseDelayMs, maxDelayMs, retryStatusCodes } = this.retryConfig;
82
+ let lastError = null;
83
+ let lastResponse = null;
84
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
85
+ try {
86
+ const response = await fetch(url, {
87
+ method,
88
+ headers: {
89
+ 'Content-Type': 'application/json',
90
+ 'X-API-Key': this.apiKey
91
+ },
92
+ body: body ? JSON.stringify(body) : undefined
93
+ });
94
+ if (retryStatusCodes.includes(response.status) && attempt < maxRetries) {
95
+ lastResponse = response;
96
+ const retryAfterHeader = response.headers.get('Retry-After');
97
+ let retryAfter;
98
+ if (retryAfterHeader) {
99
+ const parsed = parseInt(retryAfterHeader, 10);
100
+ if (!isNaN(parsed)) {
101
+ retryAfter = parsed;
102
+ }
103
+ }
104
+ const delay = calculateBackoffDelay(attempt, baseDelayMs, maxDelayMs, retryAfter);
105
+ await sleep(delay);
106
+ continue;
107
+ }
108
+ if (!response.ok) {
109
+ const errorData = await response.json().catch(() => ({}));
110
+ return {
111
+ ok: false,
112
+ status: response.status,
113
+ error: errorData.error || errorData.message || `HTTP ${response.status}`
114
+ };
115
+ }
116
+ const data = await response.json();
117
+ return {
118
+ ok: true,
119
+ status: response.status,
120
+ data
121
+ };
122
+ }
123
+ catch (error) {
124
+ lastError = error;
125
+ if (attempt < maxRetries) {
126
+ const delay = calculateBackoffDelay(attempt, baseDelayMs, maxDelayMs);
127
+ await sleep(delay);
128
+ continue;
129
+ }
130
+ }
131
+ }
132
+ if (lastResponse && !lastResponse.ok) {
133
+ return {
134
+ ok: false,
135
+ status: lastResponse.status,
136
+ error: `Request failed after ${maxRetries + 1} attempts with status ${lastResponse.status}`
137
+ };
138
+ }
139
+ return {
140
+ ok: false,
141
+ status: 0,
142
+ error: lastError?.message || 'Request failed after all retries'
143
+ };
144
+ }
145
+ /**
146
+ * Generic proxy method for operations that go through the MCP proxy endpoint
147
+ */
148
+ async proxy(operation, args, sessionContext) {
149
+ return this.request('POST', '/api/mcp/proxy', {
150
+ operation,
151
+ args,
152
+ ...sessionContext
153
+ });
154
+ }
155
+ // ============================================================================
156
+ // Session methods (delegated)
157
+ // ============================================================================
158
+ validateAuth = () => this.sessionMethods.validateAuth();
159
+ startSession = (params) => this.sessionMethods.startSession(params);
160
+ heartbeat = (sessionId, options) => this.sessionMethods.heartbeat(sessionId, options);
161
+ endSession = (sessionId) => this.sessionMethods.endSession(sessionId);
162
+ signalIdle = (sessionId) => this.sessionMethods.signalIdle(sessionId);
163
+ syncSession = (sessionId, params) => this.sessionMethods.syncSession(sessionId, params);
164
+ confirmAgentSetup = (projectId, agentType) => this.sessionMethods.confirmAgentSetup(projectId, agentType);
165
+ // ============================================================================
166
+ // Project methods (delegated)
167
+ // ============================================================================
168
+ listProjects = () => this.projectMethods.listProjects();
169
+ createProject = (params) => this.projectMethods.createProject(params);
170
+ getProject = (projectId, gitUrl) => this.projectMethods.getProject(projectId, gitUrl);
171
+ updateProject = (projectId, updates) => this.projectMethods.updateProject(projectId, updates);
172
+ getGitWorkflow = (projectId, taskId) => this.projectMethods.getGitWorkflow(projectId, taskId);
173
+ updateProjectReadme = (projectId, readmeContent) => this.projectMethods.updateProjectReadme(projectId, readmeContent);
174
+ getProjectSummary = (projectId) => this.projectMethods.getProjectSummary(projectId);
175
+ // ============================================================================
176
+ // Blockers methods (delegated)
177
+ // ============================================================================
178
+ getBlockers = (projectId, params) => this.blockersMethods.getBlockers(projectId, params);
179
+ addBlocker = (projectId, description, sessionId) => this.blockersMethods.addBlocker(projectId, description, sessionId);
180
+ resolveBlocker = (blockerId, resolutionNote) => this.blockersMethods.resolveBlocker(blockerId, resolutionNote);
181
+ deleteBlocker = (blockerId) => this.blockersMethods.deleteBlocker(blockerId);
182
+ getBlockersStats = (projectId) => this.blockersMethods.getBlockersStats(projectId);
183
+ // ============================================================================
184
+ // Cost methods (delegated)
185
+ // ============================================================================
186
+ getCostSummary = (projectId, params) => this.costMethods.getCostSummary(projectId, params);
187
+ getCostAlerts = () => this.costMethods.getCostAlerts();
188
+ addCostAlert = (params) => this.costMethods.addCostAlert(params);
189
+ updateCostAlert = (alertId, updates) => this.costMethods.updateCostAlert(alertId, updates);
190
+ deleteCostAlert = (alertId) => this.costMethods.deleteCostAlert(alertId);
191
+ getTaskCosts = (projectId, limit) => this.costMethods.getTaskCosts(projectId, limit);
192
+ getBodyOfWorkCosts = (params) => this.costMethods.getBodyOfWorkCosts(params);
193
+ getSprintCosts = (params) => this.costMethods.getSprintCosts(params);
194
+ getTokenUsage = () => this.costMethods.getTokenUsage();
195
+ reportTokenUsage = (sessionId, params) => this.costMethods.reportTokenUsage(sessionId, params);
196
+ // ============================================================================
197
+ // Worktrees methods (delegated)
198
+ // ============================================================================
199
+ getStaleWorktrees = (projectId, params) => this.worktreesMethods.getStaleWorktrees(projectId, params);
200
+ clearWorktreePath = (taskId) => this.worktreesMethods.clearWorktreePath(taskId);
201
+ // ============================================================================
202
+ // Discovery methods (delegated)
203
+ // ============================================================================
204
+ queryKnowledgeBase = (projectId, params) => this.discoveryMethods.queryKnowledgeBase(projectId, params);
205
+ getHelpTopic = (slug) => this.discoveryMethods.getHelpTopic(slug);
206
+ getHelpTopics = () => this.discoveryMethods.getHelpTopics();
207
+ // ============================================================================
208
+ // Decisions methods (delegated)
209
+ // ============================================================================
210
+ getDecisions = (projectId, options) => this.decisionsMethods.getDecisions(projectId, options);
211
+ getDecision = (decisionId) => this.decisionsMethods.getDecision(decisionId);
212
+ logDecision = (projectId, params, sessionId) => this.decisionsMethods.logDecision(projectId, params, sessionId);
213
+ deleteDecision = (decisionId) => this.decisionsMethods.deleteDecision(decisionId);
214
+ getDecisionsStats = (projectId) => this.decisionsMethods.getDecisionsStats(projectId);
215
+ // ============================================================================
216
+ // Ideas methods (delegated)
217
+ // ============================================================================
218
+ getIdeas = (projectId, params) => this.ideasMethods.getIdeas(projectId, params);
219
+ getIdea = (ideaId) => this.ideasMethods.getIdea(ideaId);
220
+ addIdea = (projectId, params, sessionId) => this.ideasMethods.addIdea(projectId, params, sessionId);
221
+ updateIdea = (ideaId, updates) => this.ideasMethods.updateIdea(ideaId, updates);
222
+ deleteIdea = (ideaId) => this.ideasMethods.deleteIdea(ideaId);
223
+ convertIdeaToTask = (ideaId, params) => this.ideasMethods.convertIdeaToTask(ideaId, params);
224
+ // ============================================================================
225
+ // Tasks methods (delegated)
226
+ // ============================================================================
227
+ getTasks = (projectId, params) => this.tasksMethods.getTasks(projectId, params);
228
+ createTask = (projectId, params) => this.tasksMethods.createTask(projectId, params);
229
+ getNextTask = (projectId, sessionId) => this.tasksMethods.getNextTask(projectId, sessionId);
230
+ getTask = (taskId) => this.tasksMethods.getTask(taskId);
231
+ getTaskById = (taskId, params) => this.tasksMethods.getTaskById(taskId, params);
232
+ searchTasks = (projectId, params) => this.tasksMethods.searchTasks(projectId, params);
233
+ getTasksByPriority = (projectId, params) => this.tasksMethods.getTasksByPriority(projectId, params);
234
+ getRecentTasks = (projectId, params) => this.tasksMethods.getRecentTasks(projectId, params);
235
+ getTaskStats = (projectId) => this.tasksMethods.getTaskStats(projectId);
236
+ updateTask = (taskId, updates) => this.tasksMethods.updateTask(taskId, updates);
237
+ completeTask = (taskId, params) => this.tasksMethods.completeTask(taskId, params);
238
+ deleteTask = (taskId) => this.tasksMethods.deleteTask(taskId);
239
+ releaseTask = (taskId, params) => this.tasksMethods.releaseTask(taskId, params);
240
+ cancelTask = (taskId, params) => this.tasksMethods.cancelTask(taskId, params);
241
+ addTaskReference = (taskId, url, label) => this.tasksMethods.addTaskReference(taskId, url, label);
242
+ removeTaskReference = (taskId, url) => this.tasksMethods.removeTaskReference(taskId, url);
243
+ batchUpdateTasks = (updates) => this.tasksMethods.batchUpdateTasks(updates);
244
+ batchCompleteTasks = (completions) => this.tasksMethods.batchCompleteTasks(completions);
245
+ }
246
+ // Singleton instance
247
+ let apiClient = null;
248
+ export function getApiClient() {
249
+ if (!apiClient) {
250
+ const apiKey = resolveApiKeyFromSources();
251
+ apiClient = new VibescopeApiClient({ apiKey });
252
+ }
253
+ return apiClient;
254
+ }
255
+ /**
256
+ * Resolve API key from multiple sources in priority order:
257
+ * 1. VIBESCOPE_API_KEY env var (CI/cloud agents)
258
+ * 2. ~/.vibescope/credentials.json (local dev)
259
+ * 3. Error with helpful message
260
+ */
261
+ function resolveApiKeyFromSources() {
262
+ // 1. Environment variable
263
+ if (process.env.VIBESCOPE_API_KEY) {
264
+ return process.env.VIBESCOPE_API_KEY;
265
+ }
266
+ // 2. Credentials file
267
+ try {
268
+ const { existsSync, readFileSync } = require('node:fs');
269
+ const { homedir } = require('node:os');
270
+ const { join } = require('node:path');
271
+ const credPath = join(homedir(), '.vibescope', 'credentials.json');
272
+ if (existsSync(credPath)) {
273
+ const data = JSON.parse(readFileSync(credPath, 'utf-8'));
274
+ if (data.apiKey) {
275
+ return data.apiKey;
276
+ }
277
+ }
278
+ }
279
+ catch {
280
+ // ignore read errors
281
+ }
282
+ // 3. Not found
283
+ throw new Error('Vibescope API key not found.\n\n' +
284
+ 'Set it up with:\n' +
285
+ ' npx vibescope init\n\n' +
286
+ 'Or set the VIBESCOPE_API_KEY environment variable.');
287
+ }
288
+ export function initApiClient(config) {
289
+ apiClient = new VibescopeApiClient(config);
290
+ return apiClient;
291
+ }
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Project API Methods
3
+ *
4
+ * Methods for project management:
5
+ * - listProjects: List all projects
6
+ * - createProject: Create a new project
7
+ * - getProject: Get project details
8
+ * - updateProject: Update project settings
9
+ * - getGitWorkflow: Get git workflow configuration
10
+ * - updateProjectReadme: Update project README
11
+ * - getProjectSummary: Get project summary
12
+ */
13
+ import type { ApiResponse, RequestFn } from './types.js';
14
+ export interface ProjectMethods {
15
+ listProjects(): Promise<ApiResponse<{
16
+ projects: Array<{
17
+ id: string;
18
+ name: string;
19
+ description?: string;
20
+ status: string;
21
+ git_url?: string;
22
+ goal?: string;
23
+ tech_stack?: string[];
24
+ }>;
25
+ }>>;
26
+ createProject(params: {
27
+ name: string;
28
+ description?: string;
29
+ goal?: string;
30
+ git_url?: string;
31
+ tech_stack?: string[];
32
+ }): Promise<ApiResponse<{
33
+ success: boolean;
34
+ project: {
35
+ id: string;
36
+ name: string;
37
+ };
38
+ }>>;
39
+ getProject(projectId: string, gitUrl?: string): Promise<ApiResponse<{
40
+ found: boolean;
41
+ project?: {
42
+ id: string;
43
+ name: string;
44
+ description?: string;
45
+ goal?: string;
46
+ status: string;
47
+ git_url?: string;
48
+ agent_instructions?: string;
49
+ tech_stack?: string[];
50
+ git_workflow?: string;
51
+ git_main_branch?: string;
52
+ git_develop_branch?: string;
53
+ git_auto_branch?: boolean;
54
+ git_auto_tag?: boolean;
55
+ deployment_instructions?: string;
56
+ };
57
+ active_tasks?: Array<{
58
+ id: string;
59
+ title: string;
60
+ description?: string;
61
+ priority: number;
62
+ status: string;
63
+ progress_percentage?: number;
64
+ estimated_minutes?: number;
65
+ }>;
66
+ open_blockers?: Array<{
67
+ id: string;
68
+ description: string;
69
+ }>;
70
+ recent_decisions?: Array<{
71
+ id: string;
72
+ title: string;
73
+ description?: string;
74
+ }>;
75
+ message?: string;
76
+ }>>;
77
+ updateProject(projectId: string, updates: {
78
+ name?: string;
79
+ description?: string;
80
+ goal?: string;
81
+ git_url?: string;
82
+ tech_stack?: string[];
83
+ status?: string;
84
+ git_workflow?: string;
85
+ git_main_branch?: string;
86
+ git_develop_branch?: string;
87
+ git_auto_branch?: boolean;
88
+ git_auto_tag?: boolean;
89
+ deployment_instructions?: string;
90
+ agent_instructions?: string;
91
+ git_delete_branch_on_merge?: boolean;
92
+ require_pr_for_validation?: boolean;
93
+ auto_merge_on_approval?: boolean;
94
+ validation_required?: boolean;
95
+ default_task_priority?: number;
96
+ require_time_estimates?: boolean;
97
+ fallback_activities_enabled?: boolean;
98
+ preferred_fallback_activities?: string[];
99
+ }): Promise<ApiResponse<{
100
+ success: boolean;
101
+ project_id: string;
102
+ }>>;
103
+ getGitWorkflow(projectId: string, taskId?: string): Promise<ApiResponse<{
104
+ workflow: string;
105
+ main_branch: string;
106
+ develop_branch?: string;
107
+ suggested_branch?: string;
108
+ base_branch?: string;
109
+ }>>;
110
+ updateProjectReadme(projectId: string, readmeContent: string): Promise<ApiResponse<{
111
+ success: boolean;
112
+ project_id: string;
113
+ }>>;
114
+ getProjectSummary(projectId: string): Promise<ApiResponse<{
115
+ project: {
116
+ id: string;
117
+ name: string;
118
+ description?: string;
119
+ goal?: string;
120
+ status: string;
121
+ };
122
+ stats: {
123
+ total_tasks: number;
124
+ completed_tasks: number;
125
+ in_progress_tasks: number;
126
+ pending_tasks: number;
127
+ open_blockers: number;
128
+ total_decisions: number;
129
+ };
130
+ }>>;
131
+ }
132
+ export declare function createProjectMethods(request: RequestFn): ProjectMethods;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Project API Methods
3
+ *
4
+ * Methods for project management:
5
+ * - listProjects: List all projects
6
+ * - createProject: Create a new project
7
+ * - getProject: Get project details
8
+ * - updateProject: Update project settings
9
+ * - getGitWorkflow: Get git workflow configuration
10
+ * - updateProjectReadme: Update project README
11
+ * - getProjectSummary: Get project summary
12
+ */
13
+ export function createProjectMethods(request) {
14
+ return {
15
+ async listProjects() {
16
+ return request('GET', '/api/mcp/projects');
17
+ },
18
+ async createProject(params) {
19
+ return request('POST', '/api/mcp/projects', params);
20
+ },
21
+ async getProject(projectId, gitUrl) {
22
+ const url = gitUrl
23
+ ? `/api/mcp/projects/${projectId}?git_url=${encodeURIComponent(gitUrl)}`
24
+ : `/api/mcp/projects/${projectId}`;
25
+ return request('GET', url);
26
+ },
27
+ async updateProject(projectId, updates) {
28
+ return request('PATCH', `/api/mcp/projects/${projectId}`, updates);
29
+ },
30
+ async getGitWorkflow(projectId, taskId) {
31
+ const url = taskId
32
+ ? `/api/mcp/projects/${projectId}/git-workflow?task_id=${taskId}`
33
+ : `/api/mcp/projects/${projectId}/git-workflow`;
34
+ return request('GET', url);
35
+ },
36
+ async updateProjectReadme(projectId, readmeContent) {
37
+ return request('PATCH', `/api/mcp/projects/${projectId}/readme`, {
38
+ readme_content: readmeContent
39
+ });
40
+ },
41
+ async getProjectSummary(projectId) {
42
+ return request('GET', `/api/mcp/projects/${projectId}/summary`);
43
+ }
44
+ };
45
+ }
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Session API Methods
3
+ *
4
+ * Methods for session lifecycle management:
5
+ * - validateAuth: Validate API key
6
+ * - startSession: Start a new work session
7
+ * - heartbeat: Maintain active status
8
+ * - endSession: End session and release tasks
9
+ * - signalIdle: Signal agent is idle
10
+ * - syncSession: Sync session state
11
+ * - confirmAgentSetup: Confirm agent setup completion
12
+ */
13
+ import type { ApiResponse, RequestFn } from './types.js';
14
+ export interface SessionMethods {
15
+ validateAuth(): Promise<ApiResponse<{
16
+ valid: boolean;
17
+ user_id: string;
18
+ api_key_id: string;
19
+ key_name: string;
20
+ }>>;
21
+ startSession(params: {
22
+ project_id?: string;
23
+ git_url?: string;
24
+ mode?: 'lite' | 'full';
25
+ model?: string;
26
+ role?: string;
27
+ hostname?: string;
28
+ agent_type?: string;
29
+ agent_name?: string;
30
+ }): Promise<ApiResponse<{
31
+ session_started: boolean;
32
+ session_id?: string;
33
+ persona?: string;
34
+ role?: string;
35
+ project?: {
36
+ id: string;
37
+ name: string;
38
+ description?: string;
39
+ goal?: string;
40
+ status?: string;
41
+ git_url?: string;
42
+ agent_instructions?: string;
43
+ tech_stack?: string[];
44
+ git_workflow?: string;
45
+ git_main_branch?: string;
46
+ git_develop_branch?: string;
47
+ git_auto_branch?: boolean;
48
+ };
49
+ active_tasks?: Array<{
50
+ id: string;
51
+ title: string;
52
+ status: string;
53
+ priority: number;
54
+ progress_percentage?: number;
55
+ estimated_minutes?: number;
56
+ }>;
57
+ blockers?: Array<{
58
+ id: string;
59
+ description: string;
60
+ status: string;
61
+ }>;
62
+ next_task?: {
63
+ id: string;
64
+ title: string;
65
+ priority: number;
66
+ estimated_minutes?: number;
67
+ } | null;
68
+ pending_requests?: Array<{
69
+ id: string;
70
+ request_type: string;
71
+ message: string;
72
+ created_at: string;
73
+ }>;
74
+ pending_requests_count?: number;
75
+ URGENT_QUESTIONS?: {
76
+ count: number;
77
+ oldest_waiting_minutes: number;
78
+ action_required: string;
79
+ requests: Array<{
80
+ id: string;
81
+ message: string;
82
+ waiting_minutes: number;
83
+ }>;
84
+ };
85
+ directive?: string;
86
+ blockers_count?: number;
87
+ validation_count?: number;
88
+ project_not_found?: boolean;
89
+ message?: string;
90
+ suggestion?: {
91
+ action: string;
92
+ example: string;
93
+ note: string;
94
+ };
95
+ agent_setup?: {
96
+ agent_type: string;
97
+ is_new_agent_type: boolean;
98
+ setup_required: boolean;
99
+ instructions: string;
100
+ config_file: string;
101
+ template_url?: string;
102
+ steps: string[];
103
+ };
104
+ stale_worktrees?: Array<{
105
+ task_id: string;
106
+ task_title: string;
107
+ worktree_path: string;
108
+ worktree_hostname?: string | null;
109
+ }>;
110
+ stale_worktrees_count?: number;
111
+ cleanup_action?: string;
112
+ awaiting_validation?: Array<{
113
+ id: string;
114
+ title?: string;
115
+ }>;
116
+ validation_priority?: boolean;
117
+ next_action?: string;
118
+ error?: string;
119
+ }>>;
120
+ heartbeat(sessionId: string, options?: {
121
+ current_worktree_path?: string | null;
122
+ hostname?: string;
123
+ }): Promise<ApiResponse<{
124
+ success: boolean;
125
+ session_id: string;
126
+ timestamp: string;
127
+ }>>;
128
+ endSession(sessionId: string): Promise<ApiResponse<{
129
+ success: boolean;
130
+ ended_session_id?: string;
131
+ session_summary?: {
132
+ agent_name: string;
133
+ tasks_completed_this_session: number;
134
+ tasks_awaiting_validation: number;
135
+ tasks_released: number;
136
+ };
137
+ reminders?: string[];
138
+ }>>;
139
+ signalIdle(sessionId: string): Promise<ApiResponse<{
140
+ success: boolean;
141
+ session_id: string;
142
+ status: string;
143
+ message: string;
144
+ }>>;
145
+ syncSession(sessionId: string, params?: {
146
+ include_project?: boolean;
147
+ include_tasks?: boolean;
148
+ }): Promise<ApiResponse<{
149
+ session: {
150
+ id: string;
151
+ status: string;
152
+ agent_name: string;
153
+ };
154
+ project?: unknown;
155
+ tasks?: unknown[];
156
+ }>>;
157
+ confirmAgentSetup(projectId: string, agentType: string): Promise<ApiResponse<{
158
+ success: boolean;
159
+ project_id: string;
160
+ agent_type: string;
161
+ }>>;
162
+ }
163
+ export declare function createSessionMethods(request: RequestFn, getApiKey: () => string): SessionMethods;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Session API Methods
3
+ *
4
+ * Methods for session lifecycle management:
5
+ * - validateAuth: Validate API key
6
+ * - startSession: Start a new work session
7
+ * - heartbeat: Maintain active status
8
+ * - endSession: End session and release tasks
9
+ * - signalIdle: Signal agent is idle
10
+ * - syncSession: Sync session state
11
+ * - confirmAgentSetup: Confirm agent setup completion
12
+ */
13
+ export function createSessionMethods(request, getApiKey) {
14
+ return {
15
+ async validateAuth() {
16
+ return request('POST', '/api/mcp/auth/validate', {
17
+ api_key: getApiKey()
18
+ });
19
+ },
20
+ async startSession(params) {
21
+ return request('POST', '/api/mcp/sessions/start', params);
22
+ },
23
+ async heartbeat(sessionId, options) {
24
+ return request('POST', '/api/mcp/sessions/heartbeat', {
25
+ session_id: sessionId,
26
+ ...options
27
+ });
28
+ },
29
+ async endSession(sessionId) {
30
+ return request('POST', '/api/mcp/sessions/end', {
31
+ session_id: sessionId
32
+ });
33
+ },
34
+ async signalIdle(sessionId) {
35
+ return request('POST', '/api/mcp/sessions/idle', {
36
+ session_id: sessionId
37
+ });
38
+ },
39
+ async syncSession(sessionId, params) {
40
+ return request('POST', '/api/mcp/sessions/sync', {
41
+ session_id: sessionId,
42
+ ...params
43
+ });
44
+ },
45
+ async confirmAgentSetup(projectId, agentType) {
46
+ return request('POST', '/api/mcp/agent-setup/confirm', {
47
+ project_id: projectId,
48
+ agent_type: agentType
49
+ });
50
+ }
51
+ };
52
+ }