@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.
@@ -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
@@ -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 top-level AGENT_RULES - critical rules agents must follow
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(`FOLLOW GIT WORKFLOW: This project uses ${projectWorkflow}. Branch from ${ruleBaseBranch}. Do NOT commit directly to main or develop.`);
292
- }
293
- agentRules.push('COMPLETE TASKS: Always call complete_task() after creating a PR. This is mandatory.');
294
- agentRules.push('REVIEW REQUIRED: All tasks must be reviewed by another agent before merging.');
295
- agentRules.push('STATUS UPDATES: Call update_agent_status(status_message: "Working on: TASK_TITLE") whenever you start a new task, and update_task(task_id, status: "in_progress") to claim it.');
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 = `start_fallback_activity(project_id: "${data.project.id}", activity: "code_review")`;
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibescope/mcp-server",
3
- "version": "0.3.14",
3
+ "version": "0.4.1",
4
4
  "description": "MCP server for Vibescope - AI project tracking tools",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
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;
@@ -321,7 +321,7 @@ export const startWorkSession: Handler = async (args, ctx) => {
321
321
  }
322
322
  }
323
323
 
324
- // Build top-level AGENT_RULES - critical rules agents must follow
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(`FOLLOW GIT WORKFLOW: This project uses ${projectWorkflow}. Branch from ${ruleBaseBranch}. Do NOT commit directly to main or develop.`);
338
+ agentRules.push(`GIT WORKFLOW: This project uses ${projectWorkflow}. Branch from ${ruleBaseBranch}. Do NOT commit directly to main or develop.`);
337
339
  }
338
- agentRules.push('COMPLETE TASKS: Always call complete_task() after creating a PR. This is mandatory.');
339
- agentRules.push('REVIEW REQUIRED: All tasks must be reviewed by another agent before merging.');
340
- agentRules.push('STATUS UPDATES: Call update_agent_status(status_message: "Working on: TASK_TITLE") whenever you start a new task, and update_task(task_id, status: "in_progress") to claim it.');
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 = `start_fallback_activity(project_id: "${data.project.id}", activity: "code_review")`;
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 };