@vibescope/mcp-server 0.2.8 → 0.2.9
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.d.ts +5 -5
- package/dist/handlers/roles.js +1 -8
- package/dist/handlers/session.js +23 -32
- package/dist/handlers/validation.js +27 -14
- package/dist/index.js +3 -3
- package/dist/templates/help-content.d.ts +24 -0
- package/dist/templates/help-content.js +1650 -0
- package/dist/tools.js +6 -13
- package/package.json +51 -51
- package/src/api-client.ts +5 -5
- package/src/handlers/roles.test.ts +5 -3
- package/src/handlers/roles.ts +1 -8
- package/src/handlers/session.ts +29 -37
- package/src/handlers/validation.ts +30 -14
- package/src/index.ts +3 -3
- package/src/templates/help-content.ts +1673 -0
- package/src/tools.ts +6 -13
package/dist/api-client.d.ts
CHANGED
|
@@ -29,10 +29,10 @@ export declare class VibescopeApiClient {
|
|
|
29
29
|
project_id?: string;
|
|
30
30
|
git_url?: string;
|
|
31
31
|
mode?: 'lite' | 'full';
|
|
32
|
-
model?:
|
|
33
|
-
role?:
|
|
32
|
+
model?: string;
|
|
33
|
+
role?: string;
|
|
34
34
|
hostname?: string;
|
|
35
|
-
agent_type?:
|
|
35
|
+
agent_type?: string;
|
|
36
36
|
}): Promise<ApiResponse<{
|
|
37
37
|
session_started: boolean;
|
|
38
38
|
session_id?: string;
|
|
@@ -970,7 +970,7 @@ export declare class VibescopeApiClient {
|
|
|
970
970
|
reportTokenUsage(sessionId: string, params: {
|
|
971
971
|
input_tokens: number;
|
|
972
972
|
output_tokens: number;
|
|
973
|
-
model?:
|
|
973
|
+
model?: string;
|
|
974
974
|
}): Promise<ApiResponse<{
|
|
975
975
|
success: boolean;
|
|
976
976
|
reported: {
|
|
@@ -1676,7 +1676,7 @@ export declare class VibescopeApiClient {
|
|
|
1676
1676
|
* Confirm that agent setup is complete for a project.
|
|
1677
1677
|
* This marks the agent type as onboarded so future sessions don't receive setup instructions.
|
|
1678
1678
|
*/
|
|
1679
|
-
confirmAgentSetup(projectId: string, agentType:
|
|
1679
|
+
confirmAgentSetup(projectId: string, agentType: string): Promise<ApiResponse<{
|
|
1680
1680
|
success: boolean;
|
|
1681
1681
|
project_id: string;
|
|
1682
1682
|
agent_type: string;
|
package/dist/handlers/roles.js
CHANGED
|
@@ -63,14 +63,7 @@ export const setSessionRole = async (args, ctx) => {
|
|
|
63
63
|
result: { error: 'role is required' },
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
|
-
|
|
67
|
-
if (!validRoles.includes(role)) {
|
|
68
|
-
return {
|
|
69
|
-
result: {
|
|
70
|
-
error: `Invalid role: ${role}. Must be one of: ${validRoles.join(', ')}`,
|
|
71
|
-
},
|
|
72
|
-
};
|
|
73
|
-
}
|
|
66
|
+
// Role is now open-ended - any role name accepted
|
|
74
67
|
// Update local session state
|
|
75
68
|
updateSession({ currentRole: role });
|
|
76
69
|
// If there's an active session, update it on the server too
|
package/dist/handlers/session.js
CHANGED
|
@@ -12,21 +12,19 @@ import os from 'os';
|
|
|
12
12
|
import { parseArgs, createEnumValidator } from '../validators.js';
|
|
13
13
|
import { getApiClient } from '../api-client.js';
|
|
14
14
|
import { getAgentGuidelinesTemplate, getAgentGuidelinesSummary } from '../templates/agent-guidelines.js';
|
|
15
|
+
import { getFallbackHelpContent, getAvailableHelpTopics } from '../templates/help-content.js';
|
|
15
16
|
// Auto-detect machine hostname for worktree tracking
|
|
16
17
|
const MACHINE_HOSTNAME = os.hostname();
|
|
17
18
|
const VALID_MODES = ['lite', 'full'];
|
|
18
|
-
const VALID_MODELS = ['opus', 'sonnet', 'haiku'];
|
|
19
|
-
const VALID_ROLES = ['developer', 'validator', 'deployer', 'reviewer', 'maintainer'];
|
|
20
|
-
const VALID_AGENT_TYPES = ['claude', 'gemini', 'cursor', 'windsurf', 'other'];
|
|
21
19
|
// Argument schemas for type-safe parsing
|
|
22
20
|
const startWorkSessionSchema = {
|
|
23
21
|
project_id: { type: 'string' },
|
|
24
22
|
git_url: { type: 'string' },
|
|
25
23
|
mode: { type: 'string', default: 'lite', validate: createEnumValidator(VALID_MODES) },
|
|
26
|
-
model: { type: 'string',
|
|
27
|
-
role: { type: 'string', default: 'developer',
|
|
24
|
+
model: { type: 'string' }, // Open-ended - any model name accepted
|
|
25
|
+
role: { type: 'string', default: 'developer' }, // Open-ended - any role name accepted
|
|
28
26
|
hostname: { type: 'string' }, // Machine hostname for worktree tracking
|
|
29
|
-
agent_type: { type: 'string'
|
|
27
|
+
agent_type: { type: 'string' }, // Open-ended - any agent type accepted
|
|
30
28
|
};
|
|
31
29
|
const heartbeatSchema = {
|
|
32
30
|
session_id: { type: 'string' },
|
|
@@ -45,17 +43,15 @@ export const startWorkSession = async (args, ctx) => {
|
|
|
45
43
|
const hostname = providedHostname || MACHINE_HOSTNAME;
|
|
46
44
|
const { session, updateSession } = ctx;
|
|
47
45
|
// Reset token tracking for new session with model info
|
|
46
|
+
// Model is now open-ended - use as-is (normalize Claude model names for consistency)
|
|
48
47
|
const normalizedModel = model ? model.toLowerCase().replace(/^claude[- ]*/i, '') : null;
|
|
49
|
-
const validModel = normalizedModel && VALID_MODELS.includes(normalizedModel)
|
|
50
|
-
? normalizedModel
|
|
51
|
-
: null;
|
|
52
48
|
updateSession({
|
|
53
49
|
tokenUsage: {
|
|
54
50
|
callCount: 0,
|
|
55
51
|
totalTokens: 0,
|
|
56
52
|
byTool: {},
|
|
57
53
|
byModel: {},
|
|
58
|
-
currentModel:
|
|
54
|
+
currentModel: normalizedModel,
|
|
59
55
|
},
|
|
60
56
|
});
|
|
61
57
|
// Require project_id or git_url
|
|
@@ -337,28 +333,23 @@ export const getHelp = async (args, _ctx) => {
|
|
|
337
333
|
const { topic } = parseArgs(args, getHelpSchema);
|
|
338
334
|
const apiClient = getApiClient();
|
|
339
335
|
const response = await apiClient.getHelpTopic(topic);
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
return {
|
|
343
|
-
result: {
|
|
344
|
-
error: response.error || `Failed to fetch help topic: ${topic}`,
|
|
345
|
-
},
|
|
346
|
-
};
|
|
336
|
+
// Try database content first
|
|
337
|
+
if (response.ok && response.data?.content) {
|
|
338
|
+
return { result: { topic, content: response.data.content } };
|
|
347
339
|
}
|
|
348
|
-
if
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
? topicsResponse.data.map(t => t.slug)
|
|
353
|
-
: ['getting_started', 'tasks', 'validation', 'deployment', 'git', 'blockers', 'milestones', 'fallback', 'session', 'tokens', 'sprints', 'topics'];
|
|
354
|
-
return {
|
|
355
|
-
result: {
|
|
356
|
-
error: `Unknown topic: ${topic}`,
|
|
357
|
-
available,
|
|
358
|
-
},
|
|
359
|
-
};
|
|
340
|
+
// Fall back to local content if database is empty or unavailable
|
|
341
|
+
const fallback = getFallbackHelpContent(topic);
|
|
342
|
+
if (fallback) {
|
|
343
|
+
return { result: { topic, content: fallback.content } };
|
|
360
344
|
}
|
|
361
|
-
|
|
345
|
+
// Topic not found in either source - show available topics
|
|
346
|
+
const available = getAvailableHelpTopics();
|
|
347
|
+
return {
|
|
348
|
+
result: {
|
|
349
|
+
error: `Unknown topic: ${topic}`,
|
|
350
|
+
available,
|
|
351
|
+
},
|
|
352
|
+
};
|
|
362
353
|
};
|
|
363
354
|
const MODEL_PRICING = {
|
|
364
355
|
standard: {
|
|
@@ -479,11 +470,11 @@ export const getTokenUsage = async (_args, ctx) => {
|
|
|
479
470
|
const reportTokenUsageSchema = {
|
|
480
471
|
input_tokens: { type: 'number', required: true },
|
|
481
472
|
output_tokens: { type: 'number', required: true },
|
|
482
|
-
model: { type: 'string',
|
|
473
|
+
model: { type: 'string' }, // Open-ended - any model name accepted
|
|
483
474
|
};
|
|
484
475
|
const confirmAgentSetupSchema = {
|
|
485
476
|
project_id: { type: 'string', required: true },
|
|
486
|
-
agent_type: { type: 'string', required: true,
|
|
477
|
+
agent_type: { type: 'string', required: true }, // Open-ended - any agent type accepted
|
|
487
478
|
};
|
|
488
479
|
/**
|
|
489
480
|
* Report actual Claude API token usage for accurate cost tracking.
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* - claim_validation
|
|
7
7
|
* - validate_task
|
|
8
8
|
*/
|
|
9
|
+
import { error, success } from './types.js';
|
|
9
10
|
import { parseArgs, uuidValidator } from '../validators.js';
|
|
10
11
|
import { getApiClient } from '../api-client.js';
|
|
11
12
|
// Argument schemas for type-safe parsing
|
|
@@ -26,9 +27,14 @@ export const getTasksAwaitingValidation = async (args, _ctx) => {
|
|
|
26
27
|
const apiClient = getApiClient();
|
|
27
28
|
const response = await apiClient.getTasksAwaitingValidation(project_id);
|
|
28
29
|
if (!response.ok) {
|
|
29
|
-
return
|
|
30
|
+
return error(response.error || 'Failed to fetch tasks awaiting validation');
|
|
30
31
|
}
|
|
31
|
-
|
|
32
|
+
// Check for application-level errors (200 OK but error in body)
|
|
33
|
+
if (response.data && typeof response.data === 'object' && 'error' in response.data) {
|
|
34
|
+
const errMsg = typeof response.data.error === 'string' ? response.data.error : 'Unknown error';
|
|
35
|
+
return error(errMsg);
|
|
36
|
+
}
|
|
37
|
+
return success(response.data);
|
|
32
38
|
};
|
|
33
39
|
export const claimValidation = async (args, ctx) => {
|
|
34
40
|
const { task_id } = parseArgs(args, claimValidationSchema);
|
|
@@ -37,9 +43,14 @@ export const claimValidation = async (args, ctx) => {
|
|
|
37
43
|
const apiClient = getApiClient();
|
|
38
44
|
const response = await apiClient.claimValidation(task_id, currentSessionId || undefined);
|
|
39
45
|
if (!response.ok) {
|
|
40
|
-
return
|
|
46
|
+
return error(response.error || 'Failed to claim task for validation');
|
|
47
|
+
}
|
|
48
|
+
// Check for application-level errors (200 OK but error in body)
|
|
49
|
+
if (response.data && typeof response.data === 'object' && 'error' in response.data) {
|
|
50
|
+
const errMsg = typeof response.data.error === 'string' ? response.data.error : 'Unknown error';
|
|
51
|
+
return error(errMsg);
|
|
41
52
|
}
|
|
42
|
-
return
|
|
53
|
+
return success(response.data);
|
|
43
54
|
};
|
|
44
55
|
export const validateTask = async (args, ctx) => {
|
|
45
56
|
const { task_id, approved, validation_notes, skip_pr_check } = parseArgs(args, validateTaskSchema);
|
|
@@ -54,18 +65,20 @@ export const validateTask = async (args, ctx) => {
|
|
|
54
65
|
if (!response.ok) {
|
|
55
66
|
// Handle PR required error specially
|
|
56
67
|
if (response.error === 'pr_required') {
|
|
57
|
-
return {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
action_required: 'Create a PR for this task and add it via add_task_reference(task_id, pr_url, label: "Pull Request")',
|
|
63
|
-
},
|
|
64
|
-
};
|
|
68
|
+
return error('pr_required', {
|
|
69
|
+
message: response.data?.message || 'A Pull Request is required before validation approval. Create a PR and add it via add_task_reference.',
|
|
70
|
+
workflow: response.data?.workflow,
|
|
71
|
+
action_required: 'Create a PR for this task and add it via add_task_reference(task_id, pr_url, label: "Pull Request")',
|
|
72
|
+
});
|
|
65
73
|
}
|
|
66
|
-
return
|
|
74
|
+
return error(response.error || 'Failed to validate task');
|
|
75
|
+
}
|
|
76
|
+
// Check for application-level errors (200 OK but error in body)
|
|
77
|
+
if (response.data && typeof response.data === 'object' && 'error' in response.data) {
|
|
78
|
+
const errMsg = typeof response.data.error === 'string' ? response.data.error : 'Unknown error';
|
|
79
|
+
return error(errMsg);
|
|
67
80
|
}
|
|
68
|
-
return
|
|
81
|
+
return success(response.data);
|
|
69
82
|
};
|
|
70
83
|
/**
|
|
71
84
|
* Validation handlers registry
|
package/dist/index.js
CHANGED
|
@@ -41,8 +41,8 @@ const handlerRegistry = buildHandlerRegistry();
|
|
|
41
41
|
// ============================================================================
|
|
42
42
|
const KNOWLEDGE_BASE = {
|
|
43
43
|
getting_started: `# Getting Started
|
|
44
|
-
1. Call start_work_session(git_url, model: "
|
|
45
|
-
- IMPORTANT: Pass your model for accurate cost tracking
|
|
44
|
+
1. Call start_work_session(git_url, model: "your-model-name") to initialize
|
|
45
|
+
- IMPORTANT: Pass your model for accurate cost tracking (e.g., "opus", "sonnet", "gemini", "gpt-4o")
|
|
46
46
|
- Check your system prompt for "You are powered by the model named..." to find it
|
|
47
47
|
2. Response includes next_task - start working on it immediately
|
|
48
48
|
3. Use update_task to mark in_progress and track progress
|
|
@@ -99,7 +99,7 @@ When no tasks available, get_next_task suggests activities:
|
|
|
99
99
|
3. stop_fallback_activity(project_id, summary: "...")`,
|
|
100
100
|
session: `# Session Management
|
|
101
101
|
- start_work_session(git_url, model) initializes and returns next_task
|
|
102
|
-
- ALWAYS pass model parameter ("opus", "sonnet", "
|
|
102
|
+
- ALWAYS pass model parameter for cost tracking (e.g., "opus", "sonnet", "gemini", "gpt-4o")
|
|
103
103
|
- Use mode:'lite' (default) or mode:'full' for complete context
|
|
104
104
|
- heartbeat every 30-60 seconds maintains active status
|
|
105
105
|
- end_work_session releases claimed tasks and returns summary
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fallback Help Content
|
|
3
|
+
*
|
|
4
|
+
* This provides comprehensive help content for each topic when the backend
|
|
5
|
+
* database has no content populated. Ensures agents always get useful guidance.
|
|
6
|
+
*/
|
|
7
|
+
export declare const HELP_TOPICS: Record<string, {
|
|
8
|
+
title: string;
|
|
9
|
+
content: string;
|
|
10
|
+
}>;
|
|
11
|
+
/**
|
|
12
|
+
* Get fallback help content for a topic
|
|
13
|
+
* @param topic The help topic slug
|
|
14
|
+
* @returns The help content or null if topic not found
|
|
15
|
+
*/
|
|
16
|
+
export declare function getFallbackHelpContent(topic: string): {
|
|
17
|
+
title: string;
|
|
18
|
+
content: string;
|
|
19
|
+
} | null;
|
|
20
|
+
/**
|
|
21
|
+
* Get list of available help topics
|
|
22
|
+
* @returns Array of topic slugs
|
|
23
|
+
*/
|
|
24
|
+
export declare function getAvailableHelpTopics(): string[];
|