@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.
- package/dist/api-client/blockers.d.ts +46 -0
- package/dist/api-client/blockers.js +43 -0
- package/dist/api-client/cost.d.ts +112 -0
- package/dist/api-client/cost.js +76 -0
- package/dist/api-client/decisions.d.ts +55 -0
- package/dist/api-client/decisions.js +32 -0
- package/dist/api-client/discovery.d.ts +62 -0
- package/dist/api-client/discovery.js +21 -0
- package/dist/api-client/ideas.d.ts +75 -0
- package/dist/api-client/ideas.js +36 -0
- package/dist/api-client/index.d.ts +749 -0
- package/dist/api-client/index.js +291 -0
- package/dist/api-client/project.d.ts +132 -0
- package/dist/api-client/project.js +45 -0
- package/dist/api-client/session.d.ts +163 -0
- package/dist/api-client/session.js +52 -0
- package/dist/api-client/tasks.d.ts +328 -0
- package/dist/api-client/tasks.js +132 -0
- package/dist/api-client/types.d.ts +25 -0
- package/dist/api-client/types.js +4 -0
- package/dist/api-client/worktrees.d.ts +33 -0
- package/dist/api-client/worktrees.js +26 -0
- package/dist/api-client.d.ts +9 -0
- package/dist/api-client.js +104 -25
- package/dist/cli-init.d.ts +17 -0
- package/dist/cli-init.js +445 -0
- package/dist/cli.js +0 -0
- package/dist/handlers/cloud-agents.d.ts +21 -0
- package/dist/handlers/cloud-agents.js +91 -0
- package/dist/handlers/discovery.js +7 -0
- package/dist/handlers/index.d.ts +1 -0
- package/dist/handlers/index.js +3 -0
- package/dist/handlers/session.js +3 -1
- package/dist/handlers/tasks.js +10 -12
- package/dist/handlers/types.d.ts +2 -1
- package/dist/handlers/validation.js +5 -1
- package/dist/index.js +8 -3
- package/dist/token-tracking.js +2 -2
- package/dist/tools/blockers.d.ts +13 -0
- package/dist/tools/blockers.js +119 -0
- package/dist/tools/bodies-of-work.d.ts +19 -0
- package/dist/tools/bodies-of-work.js +280 -0
- package/dist/tools/cloud-agents.d.ts +9 -0
- package/dist/tools/cloud-agents.js +67 -0
- package/dist/tools/connectors.d.ts +14 -0
- package/dist/tools/connectors.js +188 -0
- package/dist/tools/cost.d.ts +11 -0
- package/dist/tools/cost.js +108 -0
- package/dist/tools/decisions.d.ts +12 -0
- package/dist/tools/decisions.js +108 -0
- package/dist/tools/deployment.d.ts +24 -0
- package/dist/tools/deployment.js +439 -0
- package/dist/tools/discovery.d.ts +10 -0
- package/dist/tools/discovery.js +73 -0
- package/dist/tools/fallback.d.ts +11 -0
- package/dist/tools/fallback.js +108 -0
- package/dist/tools/file-checkouts.d.ts +13 -0
- package/dist/tools/file-checkouts.js +141 -0
- package/dist/tools/findings.d.ts +13 -0
- package/dist/tools/findings.js +98 -0
- package/dist/tools/git-issues.d.ts +11 -0
- package/dist/tools/git-issues.js +127 -0
- package/dist/tools/ideas.d.ts +13 -0
- package/dist/tools/ideas.js +159 -0
- package/dist/tools/index.d.ts +71 -0
- package/dist/tools/index.js +98 -0
- package/dist/tools/milestones.d.ts +12 -0
- package/dist/tools/milestones.js +115 -0
- package/dist/tools/organizations.d.ts +17 -0
- package/dist/tools/organizations.js +221 -0
- package/dist/tools/progress.d.ts +9 -0
- package/dist/tools/progress.js +70 -0
- package/dist/tools/project.d.ts +13 -0
- package/dist/tools/project.js +199 -0
- package/dist/tools/requests.d.ts +10 -0
- package/dist/tools/requests.js +65 -0
- package/dist/tools/roles.d.ts +11 -0
- package/dist/tools/roles.js +109 -0
- package/dist/tools/session.d.ts +15 -0
- package/dist/tools/session.js +178 -0
- package/dist/tools/sprints.d.ts +18 -0
- package/dist/tools/sprints.js +295 -0
- package/dist/tools/tasks.d.ts +27 -0
- package/dist/tools/tasks.js +539 -0
- package/dist/tools/types.d.ts +7 -0
- package/dist/tools/types.js +6 -0
- package/dist/tools/validation.d.ts +10 -0
- package/dist/tools/validation.js +72 -0
- package/dist/tools/worktrees.d.ts +9 -0
- package/dist/tools/worktrees.js +63 -0
- package/dist/utils.d.ts +66 -0
- package/dist/utils.js +102 -0
- package/docs/TOOLS.md +55 -2
- package/package.json +5 -3
- package/scripts/generate-docs.ts +1 -1
- package/src/api-client/blockers.ts +86 -0
- package/src/api-client/cost.ts +185 -0
- package/src/api-client/decisions.ts +87 -0
- package/src/api-client/discovery.ts +81 -0
- package/src/api-client/ideas.ts +112 -0
- package/src/api-client/index.ts +378 -0
- package/src/api-client/project.ts +179 -0
- package/src/api-client/session.ts +220 -0
- package/src/api-client/tasks.ts +450 -0
- package/src/api-client/types.ts +32 -0
- package/src/api-client/worktrees.ts +53 -0
- package/src/api-client.test.ts +136 -9
- package/src/api-client.ts +125 -27
- package/src/cli-init.ts +504 -0
- package/src/handlers/__test-utils__.ts +2 -0
- package/src/handlers/cloud-agents.ts +138 -0
- package/src/handlers/discovery.ts +7 -0
- package/src/handlers/index.ts +3 -0
- package/src/handlers/session.ts +3 -1
- package/src/handlers/tasks.ts +10 -12
- package/src/handlers/tool-categories.test.ts +1 -1
- package/src/handlers/types.ts +2 -1
- package/src/handlers/validation.ts +6 -1
- package/src/index.test.ts +2 -2
- package/src/index.ts +8 -2
- package/src/token-tracking.ts +3 -2
- package/src/tools/blockers.ts +122 -0
- package/src/tools/bodies-of-work.ts +283 -0
- package/src/tools/cloud-agents.ts +70 -0
- package/src/tools/connectors.ts +191 -0
- package/src/tools/cost.ts +111 -0
- package/src/tools/decisions.ts +111 -0
- package/src/tools/deployment.ts +442 -0
- package/src/tools/discovery.ts +76 -0
- package/src/tools/fallback.ts +111 -0
- package/src/tools/file-checkouts.ts +145 -0
- package/src/tools/findings.ts +101 -0
- package/src/tools/git-issues.ts +130 -0
- package/src/tools/ideas.ts +162 -0
- package/src/tools/index.ts +131 -0
- package/src/tools/milestones.ts +118 -0
- package/src/tools/organizations.ts +224 -0
- package/src/tools/progress.ts +73 -0
- package/src/tools/project.ts +202 -0
- package/src/tools/requests.ts +68 -0
- package/src/tools/roles.ts +112 -0
- package/src/tools/session.ts +181 -0
- package/src/tools/sprints.ts +298 -0
- package/src/tools/tasks.ts +542 -0
- package/src/tools/tools.test.ts +222 -0
- package/src/tools/types.ts +9 -0
- package/src/tools/validation.ts +75 -0
- package/src/tools/worktrees.ts +66 -0
- package/src/tools.test.ts +1 -1
- package/src/utils.test.ts +229 -0
- package/src/utils.ts +117 -0
- package/dist/tools.d.ts +0 -2
- package/dist/tools.js +0 -3602
- package/src/tools.ts +0 -3607
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloud Agents Handlers
|
|
3
|
+
*
|
|
4
|
+
* Handles cloud agent management:
|
|
5
|
+
* - cleanup_stale_cloud_agents
|
|
6
|
+
* - list_cloud_agents
|
|
7
|
+
*/
|
|
8
|
+
import { success, error } from './types.js';
|
|
9
|
+
import { parseArgs, uuidValidator, createEnumValidator } from '../validators.js';
|
|
10
|
+
import { getApiClient } from '../api-client.js';
|
|
11
|
+
// Argument schemas
|
|
12
|
+
const cleanupStaleAgentsSchema = {
|
|
13
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
14
|
+
stale_minutes: { type: 'number', default: 5 },
|
|
15
|
+
include_running: { type: 'boolean', default: false },
|
|
16
|
+
dry_run: { type: 'boolean', default: false },
|
|
17
|
+
};
|
|
18
|
+
const listCloudAgentsSchema = {
|
|
19
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
20
|
+
status: {
|
|
21
|
+
type: 'string',
|
|
22
|
+
default: 'all',
|
|
23
|
+
validate: createEnumValidator(['starting', 'running', 'stopped', 'failed', 'all'])
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Clean up stale cloud agents that failed to start or lost connection.
|
|
28
|
+
* Only operates on agents in the specified project (security scoped).
|
|
29
|
+
*/
|
|
30
|
+
export const cleanupStaleCloudAgents = async (args, ctx) => {
|
|
31
|
+
const { project_id, stale_minutes, include_running, dry_run } = parseArgs(args, cleanupStaleAgentsSchema);
|
|
32
|
+
// Ensure user has an active session with this project (security check)
|
|
33
|
+
if (ctx.session.currentProjectId && ctx.session.currentProjectId !== project_id) {
|
|
34
|
+
return error('Cannot cleanup agents for a different project than your current session');
|
|
35
|
+
}
|
|
36
|
+
const apiClient = getApiClient();
|
|
37
|
+
// Call the cleanup endpoint via fetch (since it's a new endpoint not in the client)
|
|
38
|
+
const response = await apiClient.proxy('cleanup_stale_cloud_agents', {
|
|
39
|
+
project_id,
|
|
40
|
+
staleMinutes: stale_minutes,
|
|
41
|
+
includeRunning: include_running,
|
|
42
|
+
dryRun: dry_run,
|
|
43
|
+
});
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
return error(response.error || 'Failed to cleanup stale agents');
|
|
46
|
+
}
|
|
47
|
+
const data = response.data;
|
|
48
|
+
if (dry_run) {
|
|
49
|
+
return success({
|
|
50
|
+
dryRun: true,
|
|
51
|
+
wouldClean: data.wouldClean || 0,
|
|
52
|
+
agents: data.agents,
|
|
53
|
+
message: `Found ${data.wouldClean || 0} stale agents that would be cleaned up`
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return success({
|
|
57
|
+
cleaned: data.cleaned,
|
|
58
|
+
failed: data.failed || 0,
|
|
59
|
+
agents: data.agents,
|
|
60
|
+
message: `Cleaned up ${data.cleaned} stale agents`
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* List cloud agents for a project with optional status filter.
|
|
65
|
+
*/
|
|
66
|
+
export const listCloudAgents = async (args, ctx) => {
|
|
67
|
+
const { project_id, status } = parseArgs(args, listCloudAgentsSchema);
|
|
68
|
+
// Ensure user has an active session with this project (security check)
|
|
69
|
+
if (ctx.session.currentProjectId && ctx.session.currentProjectId !== project_id) {
|
|
70
|
+
return error('Cannot list agents for a different project than your current session');
|
|
71
|
+
}
|
|
72
|
+
const apiClient = getApiClient();
|
|
73
|
+
const response = await apiClient.proxy('list_cloud_agents', {
|
|
74
|
+
project_id,
|
|
75
|
+
status: status === 'all' ? undefined : status,
|
|
76
|
+
});
|
|
77
|
+
if (!response.ok) {
|
|
78
|
+
return error(response.error || 'Failed to list cloud agents');
|
|
79
|
+
}
|
|
80
|
+
return success({
|
|
81
|
+
agents: response.data.agents,
|
|
82
|
+
count: response.data.agents.length
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Cloud agents handlers registry
|
|
87
|
+
*/
|
|
88
|
+
export const cloudAgentHandlers = {
|
|
89
|
+
cleanup_stale_cloud_agents: cleanupStaleCloudAgents,
|
|
90
|
+
list_cloud_agents: listCloudAgents,
|
|
91
|
+
};
|
|
@@ -316,6 +316,13 @@ export const TOOL_CATEGORIES = {
|
|
|
316
316
|
{ name: 'get_connector_events', brief: 'Event history' },
|
|
317
317
|
],
|
|
318
318
|
},
|
|
319
|
+
cloud_agents: {
|
|
320
|
+
description: 'Cloud agent management and cleanup',
|
|
321
|
+
tools: [
|
|
322
|
+
{ name: 'cleanup_stale_cloud_agents', brief: 'Clean up stale cloud agents' },
|
|
323
|
+
{ name: 'list_cloud_agents', brief: 'List cloud agents for project' },
|
|
324
|
+
],
|
|
325
|
+
},
|
|
319
326
|
};
|
|
320
327
|
export const discoverTools = async (args) => {
|
|
321
328
|
const { category } = parseArgs(args, discoverToolsSchema);
|
package/dist/handlers/index.d.ts
CHANGED
|
@@ -27,6 +27,7 @@ export * from './sprints.js';
|
|
|
27
27
|
export * from './file-checkouts.js';
|
|
28
28
|
export * from './roles.js';
|
|
29
29
|
export * from './connectors.js';
|
|
30
|
+
export * from './cloud-agents.js';
|
|
30
31
|
import type { HandlerRegistry } from './types.js';
|
|
31
32
|
/**
|
|
32
33
|
* Build the complete handler registry from all modules
|
package/dist/handlers/index.js
CHANGED
|
@@ -27,6 +27,7 @@ export * from './sprints.js';
|
|
|
27
27
|
export * from './file-checkouts.js';
|
|
28
28
|
export * from './roles.js';
|
|
29
29
|
export * from './connectors.js';
|
|
30
|
+
export * from './cloud-agents.js';
|
|
30
31
|
import { milestoneHandlers } from './milestones.js';
|
|
31
32
|
import { sessionHandlers } from './session.js';
|
|
32
33
|
import { ideaHandlers } from './ideas.js';
|
|
@@ -49,6 +50,7 @@ import { sprintHandlers } from './sprints.js';
|
|
|
49
50
|
import { fileCheckoutHandlers } from './file-checkouts.js';
|
|
50
51
|
import { roleHandlers } from './roles.js';
|
|
51
52
|
import { connectorHandlers } from './connectors.js';
|
|
53
|
+
import { cloudAgentHandlers } from './cloud-agents.js';
|
|
52
54
|
/**
|
|
53
55
|
* Build the complete handler registry from all modules
|
|
54
56
|
*/
|
|
@@ -76,5 +78,6 @@ export function buildHandlerRegistry() {
|
|
|
76
78
|
...fileCheckoutHandlers,
|
|
77
79
|
...roleHandlers,
|
|
78
80
|
...connectorHandlers,
|
|
81
|
+
...cloudAgentHandlers,
|
|
79
82
|
};
|
|
80
83
|
}
|
package/dist/handlers/session.js
CHANGED
|
@@ -26,6 +26,7 @@ const startWorkSessionSchema = {
|
|
|
26
26
|
role: { type: 'string', default: 'developer' }, // Open-ended - any role name accepted
|
|
27
27
|
hostname: { type: 'string' }, // Machine hostname for worktree tracking
|
|
28
28
|
agent_type: { type: 'string' }, // Open-ended - any agent type accepted
|
|
29
|
+
agent_name: { type: 'string' }, // Explicit agent name for cloud/remote agents (skips persona pool)
|
|
29
30
|
};
|
|
30
31
|
const heartbeatSchema = {
|
|
31
32
|
session_id: { type: 'string' },
|
|
@@ -39,7 +40,7 @@ const getHelpSchema = {
|
|
|
39
40
|
topic: { type: 'string', required: true },
|
|
40
41
|
};
|
|
41
42
|
export const startWorkSession = async (args, ctx) => {
|
|
42
|
-
const { project_id, git_url, mode, model, role, hostname: providedHostname, agent_type } = parseArgs(args, startWorkSessionSchema);
|
|
43
|
+
const { project_id, git_url, mode, model, role, hostname: providedHostname, agent_type, agent_name } = parseArgs(args, startWorkSessionSchema);
|
|
43
44
|
// Use auto-detected hostname if not provided - enables machine-aware worktree filtering
|
|
44
45
|
const hostname = providedHostname || MACHINE_HOSTNAME;
|
|
45
46
|
// Normalize git_url and track if it was changed - helps agents understand URL matching
|
|
@@ -78,6 +79,7 @@ export const startWorkSession = async (args, ctx) => {
|
|
|
78
79
|
role: role,
|
|
79
80
|
hostname, // Machine hostname for worktree tracking
|
|
80
81
|
agent_type: agent_type, // Agent type for onboarding
|
|
82
|
+
agent_name: agent_name, // Explicit name for cloud/remote agents
|
|
81
83
|
});
|
|
82
84
|
if (!response.ok) {
|
|
83
85
|
// Include additional error details if available
|
package/dist/handlers/tasks.js
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
import os from 'os';
|
|
25
25
|
import { parseArgs, uuidValidator, taskStatusValidator, priorityValidator, progressValidator, minutesValidator, createEnumValidator, ValidationError, } from '../validators.js';
|
|
26
26
|
import { getApiClient } from '../api-client.js';
|
|
27
|
+
import { capPagination, PAGINATION_LIMITS } from '../utils.js';
|
|
27
28
|
// Auto-detect machine hostname for worktree tracking
|
|
28
29
|
const MACHINE_HOSTNAME = os.hostname();
|
|
29
30
|
// Valid task types
|
|
@@ -715,9 +716,8 @@ export const searchTasks = async (args, ctx) => {
|
|
|
715
716
|
},
|
|
716
717
|
};
|
|
717
718
|
}
|
|
718
|
-
// Cap
|
|
719
|
-
const cappedLimit =
|
|
720
|
-
const safeOffset = Math.max(0, offset ?? 0);
|
|
719
|
+
// Cap pagination to safe values
|
|
720
|
+
const { cappedLimit, safeOffset } = capPagination(limit ?? 10, offset, PAGINATION_LIMITS.TASK_LIMIT);
|
|
721
721
|
const api = getApiClient();
|
|
722
722
|
const response = await api.searchTasks(project_id, {
|
|
723
723
|
query,
|
|
@@ -745,9 +745,8 @@ export const searchTasks = async (args, ctx) => {
|
|
|
745
745
|
*/
|
|
746
746
|
export const getTasksByPriority = async (args, ctx) => {
|
|
747
747
|
const { project_id, priority, priority_max, status, limit, offset } = parseArgs(args, getTasksByPrioritySchema);
|
|
748
|
-
// Cap
|
|
749
|
-
const cappedLimit =
|
|
750
|
-
const safeOffset = Math.max(0, offset ?? 0);
|
|
748
|
+
// Cap pagination to safe values
|
|
749
|
+
const { cappedLimit, safeOffset } = capPagination(limit ?? 10, offset, PAGINATION_LIMITS.TASK_LIMIT);
|
|
751
750
|
const api = getApiClient();
|
|
752
751
|
const response = await api.getTasksByPriority(project_id, {
|
|
753
752
|
priority,
|
|
@@ -776,9 +775,8 @@ export const getTasksByPriority = async (args, ctx) => {
|
|
|
776
775
|
*/
|
|
777
776
|
export const getRecentTasks = async (args, ctx) => {
|
|
778
777
|
const { project_id, order, status, limit, offset } = parseArgs(args, getRecentTasksSchema);
|
|
779
|
-
// Cap
|
|
780
|
-
const cappedLimit =
|
|
781
|
-
const safeOffset = Math.max(0, offset ?? 0);
|
|
778
|
+
// Cap pagination to safe values
|
|
779
|
+
const { cappedLimit, safeOffset } = capPagination(limit ?? 10, offset, PAGINATION_LIMITS.TASK_LIMIT);
|
|
782
780
|
const api = getApiClient();
|
|
783
781
|
const response = await api.getRecentTasks(project_id, {
|
|
784
782
|
order: order,
|
|
@@ -843,10 +841,10 @@ export const getStaleWorktrees = async (args, ctx) => {
|
|
|
843
841
|
const { project_id, hostname: providedHostname, limit, offset } = parseArgs(args, getStaleWorktreesSchema);
|
|
844
842
|
// Use auto-detected hostname if not provided - filters to only worktrees on THIS machine
|
|
845
843
|
const hostname = providedHostname || MACHINE_HOSTNAME;
|
|
846
|
-
// Cap
|
|
847
|
-
const cappedLimit =
|
|
844
|
+
// Cap pagination to safe values
|
|
845
|
+
const { cappedLimit, safeOffset } = capPagination(limit, offset, PAGINATION_LIMITS.DEFAULT_MAX_LIMIT);
|
|
848
846
|
const api = getApiClient();
|
|
849
|
-
const response = await api.getStaleWorktrees(project_id, { hostname, limit: cappedLimit, offset });
|
|
847
|
+
const response = await api.getStaleWorktrees(project_id, { hostname, limit: cappedLimit, offset: safeOffset });
|
|
850
848
|
if (!response.ok) {
|
|
851
849
|
return { result: { error: response.error || 'Failed to get stale worktrees' }, isError: true };
|
|
852
850
|
}
|
package/dist/handlers/types.d.ts
CHANGED
|
@@ -44,6 +44,7 @@ export interface SessionState {
|
|
|
44
44
|
currentSessionId: string | null;
|
|
45
45
|
currentPersona: string | null;
|
|
46
46
|
currentRole: AgentRole | null;
|
|
47
|
+
currentProjectId: string | null;
|
|
47
48
|
tokenUsage: TokenUsage;
|
|
48
49
|
}
|
|
49
50
|
/**
|
|
@@ -73,7 +74,7 @@ export interface HandlerContext {
|
|
|
73
74
|
auth: AuthContext;
|
|
74
75
|
session: SessionState;
|
|
75
76
|
/** Update session state (for handlers that modify session) */
|
|
76
|
-
updateSession: (updates: Partial<Pick<SessionState, 'currentSessionId' | 'currentPersona' | 'currentRole' | 'tokenUsage'>>) => void;
|
|
77
|
+
updateSession: (updates: Partial<Pick<SessionState, 'currentSessionId' | 'currentPersona' | 'currentRole' | 'currentProjectId' | 'tokenUsage'>>) => void;
|
|
77
78
|
/** Get user updates since last sync (for session handlers) */
|
|
78
79
|
getUserUpdates?: (projectId: string) => Promise<UserUpdates | undefined>;
|
|
79
80
|
/** Select an available persona for the agent */
|
|
@@ -21,6 +21,7 @@ const validateTaskSchema = {
|
|
|
21
21
|
approved: { type: 'boolean', required: true },
|
|
22
22
|
validation_notes: { type: 'string' },
|
|
23
23
|
skip_pr_check: { type: 'boolean' },
|
|
24
|
+
// Note: pr_checks_passing may arrive as string from some MCP clients, handled in validateTask
|
|
24
25
|
pr_checks_passing: { type: 'boolean' },
|
|
25
26
|
};
|
|
26
27
|
export const getTasksAwaitingValidation = async (args, _ctx) => {
|
|
@@ -79,12 +80,15 @@ export const validateTask = async (args, ctx) => {
|
|
|
79
80
|
const { task_id, approved, validation_notes, skip_pr_check, pr_checks_passing } = parseArgs(args, validateTaskSchema);
|
|
80
81
|
const { session } = ctx;
|
|
81
82
|
const currentSessionId = session.currentSessionId;
|
|
83
|
+
// Ensure pr_checks_passing is a proper boolean (MCP may send as string)
|
|
84
|
+
// Cast to unknown first to satisfy TypeScript
|
|
85
|
+
const checksPassingBool = pr_checks_passing === true || pr_checks_passing === 'true';
|
|
82
86
|
const apiClient = getApiClient();
|
|
83
87
|
const response = await apiClient.validateTask(task_id, {
|
|
84
88
|
approved,
|
|
85
89
|
validation_notes,
|
|
86
90
|
skip_pr_check,
|
|
87
|
-
pr_checks_passing,
|
|
91
|
+
pr_checks_passing: pr_checks_passing !== undefined ? checksPassingBool : undefined,
|
|
88
92
|
}, currentSessionId || undefined);
|
|
89
93
|
if (!response.ok) {
|
|
90
94
|
// Handle PR required error specially
|
package/dist/index.js
CHANGED
|
@@ -5,9 +5,9 @@ import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextpro
|
|
|
5
5
|
import { randomUUID } from 'crypto';
|
|
6
6
|
import { initApiClient, getApiClient } from './api-client.js';
|
|
7
7
|
import { ValidationError, } from './validators.js';
|
|
8
|
-
import { RateLimiter, } from './utils.js';
|
|
8
|
+
import { RateLimiter, getErrorMessage, } from './utils.js';
|
|
9
9
|
import { buildHandlerRegistry } from './handlers/index.js';
|
|
10
|
-
import { tools } from './tools.js';
|
|
10
|
+
import { tools } from './tools/index.js';
|
|
11
11
|
import { createTokenUsage, trackTokenUsage as trackTokens, } from './token-tracking.js';
|
|
12
12
|
// ============================================================================
|
|
13
13
|
// Agent Instance Tracking
|
|
@@ -20,6 +20,8 @@ let currentSessionId = null;
|
|
|
20
20
|
let currentPersona = null;
|
|
21
21
|
// Current role for this agent instance
|
|
22
22
|
let currentRole = null;
|
|
23
|
+
// Current project ID for this agent instance
|
|
24
|
+
let currentProjectId = null;
|
|
23
25
|
// Token usage tracking for this session (using token-tracking module)
|
|
24
26
|
let sessionTokenUsage = createTokenUsage();
|
|
25
27
|
// Wrapper function to track token usage with the session's usage object
|
|
@@ -177,6 +179,7 @@ async function handleTool(auth, name, args) {
|
|
|
177
179
|
currentSessionId,
|
|
178
180
|
currentPersona,
|
|
179
181
|
currentRole,
|
|
182
|
+
currentProjectId,
|
|
180
183
|
tokenUsage: sessionTokenUsage,
|
|
181
184
|
},
|
|
182
185
|
updateSession: (updates) => {
|
|
@@ -186,6 +189,8 @@ async function handleTool(auth, name, args) {
|
|
|
186
189
|
currentPersona = updates.currentPersona;
|
|
187
190
|
if (updates.currentRole !== undefined)
|
|
188
191
|
currentRole = updates.currentRole;
|
|
192
|
+
if (updates.currentProjectId !== undefined)
|
|
193
|
+
currentProjectId = updates.currentProjectId;
|
|
189
194
|
if (updates.tokenUsage !== undefined)
|
|
190
195
|
sessionTokenUsage = updates.tokenUsage;
|
|
191
196
|
},
|
|
@@ -293,7 +298,7 @@ async function main() {
|
|
|
293
298
|
};
|
|
294
299
|
}
|
|
295
300
|
// Handle database errors with better context
|
|
296
|
-
const errorMessage = error
|
|
301
|
+
const errorMessage = getErrorMessage(error);
|
|
297
302
|
let hint;
|
|
298
303
|
if (errorMessage.includes('violates foreign key constraint')) {
|
|
299
304
|
hint = 'The referenced ID does not exist. Check that the project_id, task_id, or other IDs are correct.';
|
package/dist/token-tracking.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Functions for estimating and tracking token usage across MCP tool calls.
|
|
5
5
|
* Extracted from index.ts to enable unit testing.
|
|
6
6
|
*/
|
|
7
|
+
import { getErrorMessage } from './utils.js';
|
|
7
8
|
// ============================================================================
|
|
8
9
|
// Token Estimation
|
|
9
10
|
// ============================================================================
|
|
@@ -21,8 +22,7 @@ export function estimateTokens(obj) {
|
|
|
21
22
|
}
|
|
22
23
|
catch (error) {
|
|
23
24
|
// Log warning when serialization fails (e.g., circular references, BigInt)
|
|
24
|
-
|
|
25
|
-
console.warn(`[Vibescope] Token estimation failed: ${errorMessage}. Returning minimal estimate of 1 token.`);
|
|
25
|
+
console.warn(`[Vibescope] Token estimation failed: ${getErrorMessage(error)}. Returning minimal estimate of 1 token.`);
|
|
26
26
|
return 1;
|
|
27
27
|
}
|
|
28
28
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Blocker Tool Definitions
|
|
3
|
+
*
|
|
4
|
+
* Tools for managing blockers:
|
|
5
|
+
* - add_blocker
|
|
6
|
+
* - resolve_blocker
|
|
7
|
+
* - get_blocker
|
|
8
|
+
* - get_blockers
|
|
9
|
+
* - get_blockers_stats
|
|
10
|
+
* - delete_blocker
|
|
11
|
+
*/
|
|
12
|
+
import type { Tool } from './types.js';
|
|
13
|
+
export declare const blockerTools: Tool[];
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Blocker Tool Definitions
|
|
3
|
+
*
|
|
4
|
+
* Tools for managing blockers:
|
|
5
|
+
* - add_blocker
|
|
6
|
+
* - resolve_blocker
|
|
7
|
+
* - get_blocker
|
|
8
|
+
* - get_blockers
|
|
9
|
+
* - get_blockers_stats
|
|
10
|
+
* - delete_blocker
|
|
11
|
+
*/
|
|
12
|
+
export const blockerTools = [
|
|
13
|
+
{
|
|
14
|
+
name: 'add_blocker',
|
|
15
|
+
description: `Record a blocker preventing progress.`,
|
|
16
|
+
inputSchema: {
|
|
17
|
+
type: 'object',
|
|
18
|
+
properties: {
|
|
19
|
+
project_id: {
|
|
20
|
+
type: 'string',
|
|
21
|
+
description: 'Project UUID',
|
|
22
|
+
},
|
|
23
|
+
description: {
|
|
24
|
+
type: 'string',
|
|
25
|
+
description: 'What is blocking progress?',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
required: ['project_id', 'description'],
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'resolve_blocker',
|
|
33
|
+
description: `Mark a blocker as resolved.`,
|
|
34
|
+
inputSchema: {
|
|
35
|
+
type: 'object',
|
|
36
|
+
properties: {
|
|
37
|
+
blocker_id: {
|
|
38
|
+
type: 'string',
|
|
39
|
+
description: 'Blocker UUID',
|
|
40
|
+
},
|
|
41
|
+
resolution_note: {
|
|
42
|
+
type: 'string',
|
|
43
|
+
description: 'How was it resolved?',
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
required: ['blocker_id'],
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'get_blocker',
|
|
51
|
+
description: `Get a single blocker by ID. More token-efficient than get_blockers when you need details for a specific blocker.`,
|
|
52
|
+
inputSchema: {
|
|
53
|
+
type: 'object',
|
|
54
|
+
properties: {
|
|
55
|
+
blocker_id: {
|
|
56
|
+
type: 'string',
|
|
57
|
+
description: 'Blocker UUID',
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
required: ['blocker_id'],
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: 'get_blockers',
|
|
65
|
+
description: `Get blockers for a project, optionally filtered by status.`,
|
|
66
|
+
inputSchema: {
|
|
67
|
+
type: 'object',
|
|
68
|
+
properties: {
|
|
69
|
+
project_id: {
|
|
70
|
+
type: 'string',
|
|
71
|
+
description: 'Project UUID',
|
|
72
|
+
},
|
|
73
|
+
status: {
|
|
74
|
+
type: 'string',
|
|
75
|
+
enum: ['open', 'resolved'],
|
|
76
|
+
description: 'Filter by status (default: open)',
|
|
77
|
+
},
|
|
78
|
+
limit: {
|
|
79
|
+
type: 'number',
|
|
80
|
+
description: 'Max number of blockers to return (default 10, max 200)',
|
|
81
|
+
},
|
|
82
|
+
offset: {
|
|
83
|
+
type: 'number',
|
|
84
|
+
description: 'Number of blockers to skip for pagination (default 0)',
|
|
85
|
+
},
|
|
86
|
+
search_query: {
|
|
87
|
+
type: 'string',
|
|
88
|
+
description: 'Search blockers by description',
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
required: ['project_id'],
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: 'get_blockers_stats',
|
|
96
|
+
description: `Get aggregate statistics about blockers for a project. Returns total count and breakdown by status. Much more token-efficient than get_blockers when you just need to understand the overall state.`,
|
|
97
|
+
inputSchema: {
|
|
98
|
+
type: 'object',
|
|
99
|
+
properties: {
|
|
100
|
+
project_id: { type: 'string', description: 'Project UUID' },
|
|
101
|
+
},
|
|
102
|
+
required: ['project_id'],
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: 'delete_blocker',
|
|
107
|
+
description: `Delete a blocker.`,
|
|
108
|
+
inputSchema: {
|
|
109
|
+
type: 'object',
|
|
110
|
+
properties: {
|
|
111
|
+
blocker_id: {
|
|
112
|
+
type: 'string',
|
|
113
|
+
description: 'Blocker UUID',
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
required: ['blocker_id'],
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
];
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bodies of Work Tool Definitions
|
|
3
|
+
*
|
|
4
|
+
* Tools for managing grouped task collections:
|
|
5
|
+
* - create_body_of_work
|
|
6
|
+
* - update_body_of_work
|
|
7
|
+
* - get_body_of_work
|
|
8
|
+
* - get_bodies_of_work
|
|
9
|
+
* - delete_body_of_work
|
|
10
|
+
* - add_task_to_body_of_work
|
|
11
|
+
* - remove_task_from_body_of_work
|
|
12
|
+
* - activate_body_of_work
|
|
13
|
+
* - add_task_dependency
|
|
14
|
+
* - remove_task_dependency
|
|
15
|
+
* - get_task_dependencies
|
|
16
|
+
* - get_next_body_of_work_task
|
|
17
|
+
*/
|
|
18
|
+
import type { Tool } from './types.js';
|
|
19
|
+
export declare const bodiesOfWorkTools: Tool[];
|