@vibescope/mcp-server 0.3.14 → 0.4.1
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 +4 -0
- package/dist/cli-init.js +0 -0
- package/dist/cli.js +0 -0
- package/dist/handlers/session.js +86 -8
- package/dist/index.js +0 -0
- package/package.json +1 -1
- package/src/api-client.ts +4 -0
- package/src/handlers/session.ts +94 -7
package/dist/api-client.d.ts
CHANGED
|
@@ -60,6 +60,10 @@ export declare class VibescopeApiClient {
|
|
|
60
60
|
git_main_branch?: string;
|
|
61
61
|
git_develop_branch?: string;
|
|
62
62
|
git_auto_branch?: boolean;
|
|
63
|
+
validation_required?: boolean;
|
|
64
|
+
auto_merge_on_approval?: boolean;
|
|
65
|
+
fallback_activities_enabled?: boolean;
|
|
66
|
+
require_pr_for_validation?: boolean;
|
|
63
67
|
};
|
|
64
68
|
active_tasks?: Array<{
|
|
65
69
|
id: string;
|
package/dist/cli-init.js
CHANGED
|
File without changes
|
package/dist/cli.js
CHANGED
|
File without changes
|
package/dist/handlers/session.js
CHANGED
|
@@ -277,23 +277,99 @@ export const startWorkSession = async (args, ctx) => {
|
|
|
277
277
|
result.directive = `SETUP REQUIRED: This is your first time connecting as a ${data.agent_setup.agent_type} agent. Follow the agent_setup instructions before starting work.`;
|
|
278
278
|
}
|
|
279
279
|
}
|
|
280
|
-
// Build
|
|
280
|
+
// Build dynamic AGENT_RULES from project settings
|
|
281
281
|
const agentRules = [];
|
|
282
282
|
const projectWorkflow = data.project?.git_workflow;
|
|
283
283
|
const isBranching = projectWorkflow === 'git-flow' || projectWorkflow === 'github-flow';
|
|
284
284
|
const ruleBaseBranch = projectWorkflow === 'git-flow'
|
|
285
285
|
? (data.project?.git_develop_branch || 'develop')
|
|
286
286
|
: (data.project?.git_main_branch || 'main');
|
|
287
|
+
// Git workflow rules (dynamic based on project settings)
|
|
287
288
|
if (isBranching) {
|
|
288
289
|
agentRules.push(`WORKTREE REQUIRED: Create a git worktree BEFORE making ANY file edits. Command: git worktree add ../PROJECT-PERSONA-task -b feature/TASKID-desc ${ruleBaseBranch}`);
|
|
290
|
+
agentRules.push(`REBASE BEFORE PR: Always rebase onto ${ruleBaseBranch} before creating a PR. Run: git fetch origin && git rebase origin/${ruleBaseBranch} && git push --force-with-lease. This prevents overwriting other agents' work.`);
|
|
289
291
|
}
|
|
290
292
|
if (projectWorkflow && projectWorkflow !== 'none') {
|
|
291
|
-
agentRules.push(`
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
agentRules.push('
|
|
295
|
-
agentRules.push('
|
|
293
|
+
agentRules.push(`GIT WORKFLOW: This project uses ${projectWorkflow}. Branch from ${ruleBaseBranch}. Do NOT commit directly to main or develop.`);
|
|
294
|
+
}
|
|
295
|
+
// Task lifecycle rules
|
|
296
|
+
agentRules.push('COMPLETE TASKS: Always call complete_task(task_id, summary, session_id) immediately after creating a PR. This is mandatory — it updates the dashboard and triggers validation.');
|
|
297
|
+
agentRules.push('SESSION ID: Pass session_id on EVERY update_task and complete_task call. Without it, the dashboard shows "Agent" instead of your name.');
|
|
298
|
+
agentRules.push('STATUS UPDATES: Call update_agent_status(status_message: "Working on: TASK_TITLE") whenever you start or finish a task.');
|
|
299
|
+
agentRules.push('TRACK PROGRESS: Call update_task with progress_percentage (0-100) every 15-20% of task completion.');
|
|
300
|
+
// Validation rules (dynamic based on project settings)
|
|
301
|
+
if (data.project?.validation_required !== false) {
|
|
302
|
+
agentRules.push('REVIEW REQUIRED: All completed tasks must be reviewed/validated by another agent before merging.');
|
|
303
|
+
}
|
|
304
|
+
if (data.project?.auto_merge_on_approval !== false) {
|
|
305
|
+
agentRules.push('AUTO-MERGE: After approving a PR during validation, merge it immediately with `gh pr merge --squash`.');
|
|
306
|
+
}
|
|
307
|
+
// Autonomy rules
|
|
308
|
+
agentRules.push('BE AUTONOMOUS: Pick up tasks without asking permission. Never ask "Should I continue?" — just continue to the next task.');
|
|
309
|
+
agentRules.push('BREAK DOWN COMPLEX TASKS: If a task is too large, create subtasks with add_subtask() and start on the first one immediately.');
|
|
296
310
|
result.AGENT_RULES = agentRules;
|
|
311
|
+
// Build WORKFLOW section — dynamic step-by-step instructions
|
|
312
|
+
// This replaces the hardcoded workflow in CLAUDE.md
|
|
313
|
+
const workflow = {};
|
|
314
|
+
// Continuous work loop
|
|
315
|
+
workflow.continuous_work = {
|
|
316
|
+
description: 'After completing a task, immediately continue to the next one.',
|
|
317
|
+
steps: [
|
|
318
|
+
'complete_task(task_id, summary, session_id) — returns next_task if available',
|
|
319
|
+
'If no next_task returned: call get_next_task(project_id)',
|
|
320
|
+
'If no tasks available: call get_pending_requests(project_id) and handle any',
|
|
321
|
+
'If still nothing: call signal_idle() then start_fallback_activity(project_id, activity: "code_review")',
|
|
322
|
+
],
|
|
323
|
+
rule: 'Never ask permission. Never stop working while tasks exist.',
|
|
324
|
+
};
|
|
325
|
+
// Validation workflow (only if validation is enabled)
|
|
326
|
+
if (data.project?.validation_required !== false) {
|
|
327
|
+
workflow.validation = {
|
|
328
|
+
description: 'How to validate/review completed tasks. Review PRs in FIFO order (lowest PR number first).',
|
|
329
|
+
steps: [
|
|
330
|
+
'claim_validation(task_id) — returns worktree setup commands and PR info',
|
|
331
|
+
`Set up worktree from existing branch: git fetch origin feature/xxx && git worktree add ../PROJECT-PERSONA-validation feature/xxx`,
|
|
332
|
+
'Review code, run tests if applicable',
|
|
333
|
+
'Verify PR checks: gh pr view <PR> --json statusCheckRollup,mergeable',
|
|
334
|
+
'Approve: validate_task(task_id, approved: true, pr_checks_passing: true, validation_notes: "...")',
|
|
335
|
+
data.project?.auto_merge_on_approval !== false
|
|
336
|
+
? 'Merge immediately: gh pr merge <PR> --squash'
|
|
337
|
+
: 'Do NOT merge — wait for project owner to merge.',
|
|
338
|
+
'Reject: validate_task(task_id, approved: false, validation_notes: "...", create_fix_task: true)',
|
|
339
|
+
'Clean up worktree after validation',
|
|
340
|
+
],
|
|
341
|
+
handle_failures: {
|
|
342
|
+
tests_fail: 'Use create_fix_task: true in validate_task() to create a follow-up task',
|
|
343
|
+
merge_conflicts: 'Create a task: add_task(project_id, title: "Resolve merge conflicts in PR #XXX")',
|
|
344
|
+
minor_issues: 'Fix directly in the branch, push, and re-validate',
|
|
345
|
+
closed_pr: 'cancel_task(task_id, cancelled_reason: "pr_closed")',
|
|
346
|
+
},
|
|
347
|
+
rule: 'Every PR review MUST end with a clear action. Never leave PRs unmerged or unresolved.',
|
|
348
|
+
};
|
|
349
|
+
// Post-merge branch sync (git-flow only)
|
|
350
|
+
if (projectWorkflow === 'git-flow' && data.project) {
|
|
351
|
+
const devBranch = data.project.git_develop_branch || 'develop';
|
|
352
|
+
workflow.post_merge_sync = {
|
|
353
|
+
description: `After merging to main, sync main back to ${devBranch} to prevent divergence.`,
|
|
354
|
+
commands: [
|
|
355
|
+
`git checkout ${devBranch} && git pull origin ${devBranch}`,
|
|
356
|
+
'git merge origin/main',
|
|
357
|
+
`git push origin ${devBranch}`,
|
|
358
|
+
],
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
// Deployment resolution workflow
|
|
363
|
+
workflow.deployment_resolution = {
|
|
364
|
+
description: 'When a fix already exists but just needs deployment',
|
|
365
|
+
steps: [
|
|
366
|
+
'add_finding(project_id, title: "Fix exists - needs deployment", category: "other", severity: "info")',
|
|
367
|
+
'complete_task(task_id, summary: "Fix exists in [branch/commit], pending deployment", session_id)',
|
|
368
|
+
'check_deployment_status(project_id) then request_deployment(project_id) if needed',
|
|
369
|
+
],
|
|
370
|
+
rule: 'Don\'t block tasks waiting for deployment — investigation is complete when you identify the resolution.',
|
|
371
|
+
};
|
|
372
|
+
result.WORKFLOW = workflow;
|
|
297
373
|
// Add next action at end - pending requests take priority over validation, then regular tasks
|
|
298
374
|
if (hasUrgentQuestions) {
|
|
299
375
|
const firstQuestion = data.URGENT_QUESTIONS?.requests?.[0] || data.pending_requests?.[0];
|
|
@@ -306,10 +382,12 @@ export const startWorkSession = async (args, ctx) => {
|
|
|
306
382
|
result.next_action = data.next_action || `claim_validation(task_id: "${data.awaiting_validation[0].id}")`;
|
|
307
383
|
}
|
|
308
384
|
else if (data.next_task) {
|
|
309
|
-
result.next_action = `update_task(task_id: "${data.next_task.id}", status: "in_progress")`;
|
|
385
|
+
result.next_action = `update_task(task_id: "${data.next_task.id}", status: "in_progress", session_id: "${result.session_id}")`;
|
|
310
386
|
}
|
|
311
387
|
else if (data.project) {
|
|
312
|
-
result.next_action =
|
|
388
|
+
result.next_action = data.project.fallback_activities_enabled !== false
|
|
389
|
+
? `start_fallback_activity(project_id: "${data.project.id}", activity: "code_review")`
|
|
390
|
+
: 'signal_idle() — no tasks available and fallback activities are disabled.';
|
|
313
391
|
}
|
|
314
392
|
return { result };
|
|
315
393
|
};
|
package/dist/index.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
package/src/api-client.ts
CHANGED
|
@@ -203,6 +203,10 @@ export class VibescopeApiClient {
|
|
|
203
203
|
git_main_branch?: string;
|
|
204
204
|
git_develop_branch?: string;
|
|
205
205
|
git_auto_branch?: boolean;
|
|
206
|
+
validation_required?: boolean;
|
|
207
|
+
auto_merge_on_approval?: boolean;
|
|
208
|
+
fallback_activities_enabled?: boolean;
|
|
209
|
+
require_pr_for_validation?: boolean;
|
|
206
210
|
};
|
|
207
211
|
active_tasks?: Array<{
|
|
208
212
|
id: string;
|
package/src/handlers/session.ts
CHANGED
|
@@ -321,7 +321,7 @@ export const startWorkSession: Handler = async (args, ctx) => {
|
|
|
321
321
|
}
|
|
322
322
|
}
|
|
323
323
|
|
|
324
|
-
// Build
|
|
324
|
+
// Build dynamic AGENT_RULES from project settings
|
|
325
325
|
const agentRules: string[] = [];
|
|
326
326
|
const projectWorkflow = data.project?.git_workflow;
|
|
327
327
|
const isBranching = projectWorkflow === 'git-flow' || projectWorkflow === 'github-flow';
|
|
@@ -329,18 +329,103 @@ export const startWorkSession: Handler = async (args, ctx) => {
|
|
|
329
329
|
? (data.project?.git_develop_branch || 'develop')
|
|
330
330
|
: (data.project?.git_main_branch || 'main');
|
|
331
331
|
|
|
332
|
+
// Git workflow rules (dynamic based on project settings)
|
|
332
333
|
if (isBranching) {
|
|
333
334
|
agentRules.push(`WORKTREE REQUIRED: Create a git worktree BEFORE making ANY file edits. Command: git worktree add ../PROJECT-PERSONA-task -b feature/TASKID-desc ${ruleBaseBranch}`);
|
|
335
|
+
agentRules.push(`REBASE BEFORE PR: Always rebase onto ${ruleBaseBranch} before creating a PR. Run: git fetch origin && git rebase origin/${ruleBaseBranch} && git push --force-with-lease. This prevents overwriting other agents' work.`);
|
|
334
336
|
}
|
|
335
337
|
if (projectWorkflow && projectWorkflow !== 'none') {
|
|
336
|
-
agentRules.push(`
|
|
338
|
+
agentRules.push(`GIT WORKFLOW: This project uses ${projectWorkflow}. Branch from ${ruleBaseBranch}. Do NOT commit directly to main or develop.`);
|
|
337
339
|
}
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
agentRules.push('
|
|
340
|
+
|
|
341
|
+
// Task lifecycle rules
|
|
342
|
+
agentRules.push('COMPLETE TASKS: Always call complete_task(task_id, summary, session_id) immediately after creating a PR. This is mandatory — it updates the dashboard and triggers validation.');
|
|
343
|
+
agentRules.push('SESSION ID: Pass session_id on EVERY update_task and complete_task call. Without it, the dashboard shows "Agent" instead of your name.');
|
|
344
|
+
agentRules.push('STATUS UPDATES: Call update_agent_status(status_message: "Working on: TASK_TITLE") whenever you start or finish a task.');
|
|
345
|
+
agentRules.push('TRACK PROGRESS: Call update_task with progress_percentage (0-100) every 15-20% of task completion.');
|
|
346
|
+
|
|
347
|
+
// Validation rules (dynamic based on project settings)
|
|
348
|
+
if (data.project?.validation_required !== false) {
|
|
349
|
+
agentRules.push('REVIEW REQUIRED: All completed tasks must be reviewed/validated by another agent before merging.');
|
|
350
|
+
}
|
|
351
|
+
if (data.project?.auto_merge_on_approval !== false) {
|
|
352
|
+
agentRules.push('AUTO-MERGE: After approving a PR during validation, merge it immediately with `gh pr merge --squash`.');
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// Autonomy rules
|
|
356
|
+
agentRules.push('BE AUTONOMOUS: Pick up tasks without asking permission. Never ask "Should I continue?" — just continue to the next task.');
|
|
357
|
+
agentRules.push('BREAK DOWN COMPLEX TASKS: If a task is too large, create subtasks with add_subtask() and start on the first one immediately.');
|
|
341
358
|
|
|
342
359
|
result.AGENT_RULES = agentRules;
|
|
343
360
|
|
|
361
|
+
// Build WORKFLOW section — dynamic step-by-step instructions
|
|
362
|
+
// This replaces the hardcoded workflow in CLAUDE.md
|
|
363
|
+
const workflow: Record<string, unknown> = {};
|
|
364
|
+
|
|
365
|
+
// Continuous work loop
|
|
366
|
+
workflow.continuous_work = {
|
|
367
|
+
description: 'After completing a task, immediately continue to the next one.',
|
|
368
|
+
steps: [
|
|
369
|
+
'complete_task(task_id, summary, session_id) — returns next_task if available',
|
|
370
|
+
'If no next_task returned: call get_next_task(project_id)',
|
|
371
|
+
'If no tasks available: call get_pending_requests(project_id) and handle any',
|
|
372
|
+
'If still nothing: call signal_idle() then start_fallback_activity(project_id, activity: "code_review")',
|
|
373
|
+
],
|
|
374
|
+
rule: 'Never ask permission. Never stop working while tasks exist.',
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
// Validation workflow (only if validation is enabled)
|
|
378
|
+
if (data.project?.validation_required !== false) {
|
|
379
|
+
workflow.validation = {
|
|
380
|
+
description: 'How to validate/review completed tasks. Review PRs in FIFO order (lowest PR number first).',
|
|
381
|
+
steps: [
|
|
382
|
+
'claim_validation(task_id) — returns worktree setup commands and PR info',
|
|
383
|
+
`Set up worktree from existing branch: git fetch origin feature/xxx && git worktree add ../PROJECT-PERSONA-validation feature/xxx`,
|
|
384
|
+
'Review code, run tests if applicable',
|
|
385
|
+
'Verify PR checks: gh pr view <PR> --json statusCheckRollup,mergeable',
|
|
386
|
+
'Approve: validate_task(task_id, approved: true, pr_checks_passing: true, validation_notes: "...")',
|
|
387
|
+
data.project?.auto_merge_on_approval !== false
|
|
388
|
+
? 'Merge immediately: gh pr merge <PR> --squash'
|
|
389
|
+
: 'Do NOT merge — wait for project owner to merge.',
|
|
390
|
+
'Reject: validate_task(task_id, approved: false, validation_notes: "...", create_fix_task: true)',
|
|
391
|
+
'Clean up worktree after validation',
|
|
392
|
+
],
|
|
393
|
+
handle_failures: {
|
|
394
|
+
tests_fail: 'Use create_fix_task: true in validate_task() to create a follow-up task',
|
|
395
|
+
merge_conflicts: 'Create a task: add_task(project_id, title: "Resolve merge conflicts in PR #XXX")',
|
|
396
|
+
minor_issues: 'Fix directly in the branch, push, and re-validate',
|
|
397
|
+
closed_pr: 'cancel_task(task_id, cancelled_reason: "pr_closed")',
|
|
398
|
+
},
|
|
399
|
+
rule: 'Every PR review MUST end with a clear action. Never leave PRs unmerged or unresolved.',
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
// Post-merge branch sync (git-flow only)
|
|
403
|
+
if (projectWorkflow === 'git-flow' && data.project) {
|
|
404
|
+
const devBranch = data.project.git_develop_branch || 'develop';
|
|
405
|
+
workflow.post_merge_sync = {
|
|
406
|
+
description: `After merging to main, sync main back to ${devBranch} to prevent divergence.`,
|
|
407
|
+
commands: [
|
|
408
|
+
`git checkout ${devBranch} && git pull origin ${devBranch}`,
|
|
409
|
+
'git merge origin/main',
|
|
410
|
+
`git push origin ${devBranch}`,
|
|
411
|
+
],
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// Deployment resolution workflow
|
|
417
|
+
workflow.deployment_resolution = {
|
|
418
|
+
description: 'When a fix already exists but just needs deployment',
|
|
419
|
+
steps: [
|
|
420
|
+
'add_finding(project_id, title: "Fix exists - needs deployment", category: "other", severity: "info")',
|
|
421
|
+
'complete_task(task_id, summary: "Fix exists in [branch/commit], pending deployment", session_id)',
|
|
422
|
+
'check_deployment_status(project_id) then request_deployment(project_id) if needed',
|
|
423
|
+
],
|
|
424
|
+
rule: 'Don\'t block tasks waiting for deployment — investigation is complete when you identify the resolution.',
|
|
425
|
+
};
|
|
426
|
+
|
|
427
|
+
result.WORKFLOW = workflow;
|
|
428
|
+
|
|
344
429
|
// Add next action at end - pending requests take priority over validation, then regular tasks
|
|
345
430
|
if (hasUrgentQuestions) {
|
|
346
431
|
const firstQuestion = data.URGENT_QUESTIONS?.requests?.[0] || data.pending_requests?.[0];
|
|
@@ -351,9 +436,11 @@ export const startWorkSession: Handler = async (args, ctx) => {
|
|
|
351
436
|
// Validation tasks take priority over new work - use next_action from API if available
|
|
352
437
|
result.next_action = data.next_action || `claim_validation(task_id: "${data.awaiting_validation[0].id}")`;
|
|
353
438
|
} else if (data.next_task) {
|
|
354
|
-
result.next_action = `update_task(task_id: "${data.next_task.id}", status: "in_progress")`;
|
|
439
|
+
result.next_action = `update_task(task_id: "${data.next_task.id}", status: "in_progress", session_id: "${result.session_id}")`;
|
|
355
440
|
} else if (data.project) {
|
|
356
|
-
result.next_action =
|
|
441
|
+
result.next_action = data.project.fallback_activities_enabled !== false
|
|
442
|
+
? `start_fallback_activity(project_id: "${data.project.id}", activity: "code_review")`
|
|
443
|
+
: 'signal_idle() — no tasks available and fallback activities are disabled.';
|
|
357
444
|
}
|
|
358
445
|
|
|
359
446
|
return { result };
|