@vibescope/mcp-server 0.2.0 → 0.2.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.
Files changed (65) hide show
  1. package/dist/api-client.d.ts +64 -1
  2. package/dist/api-client.js +34 -3
  3. package/dist/handlers/bodies-of-work.js +82 -49
  4. package/dist/handlers/cost.js +62 -54
  5. package/dist/handlers/decisions.js +29 -16
  6. package/dist/handlers/deployment.js +112 -106
  7. package/dist/handlers/discovery.js +35 -5
  8. package/dist/handlers/fallback.js +24 -19
  9. package/dist/handlers/file-checkouts.d.ts +18 -0
  10. package/dist/handlers/file-checkouts.js +101 -0
  11. package/dist/handlers/findings.d.ts +6 -0
  12. package/dist/handlers/findings.js +85 -30
  13. package/dist/handlers/git-issues.js +36 -32
  14. package/dist/handlers/ideas.js +44 -26
  15. package/dist/handlers/index.d.ts +2 -0
  16. package/dist/handlers/index.js +6 -0
  17. package/dist/handlers/milestones.js +34 -27
  18. package/dist/handlers/organizations.js +86 -78
  19. package/dist/handlers/progress.js +22 -11
  20. package/dist/handlers/project.js +62 -22
  21. package/dist/handlers/requests.js +15 -11
  22. package/dist/handlers/roles.d.ts +18 -0
  23. package/dist/handlers/roles.js +130 -0
  24. package/dist/handlers/session.js +30 -8
  25. package/dist/handlers/sprints.js +76 -64
  26. package/dist/handlers/tasks.js +113 -73
  27. package/dist/handlers/validation.js +18 -14
  28. package/dist/tools.js +387 -0
  29. package/package.json +1 -1
  30. package/src/api-client.ts +89 -6
  31. package/src/handlers/__test-setup__.ts +7 -0
  32. package/src/handlers/bodies-of-work.ts +101 -101
  33. package/src/handlers/cost.test.ts +34 -44
  34. package/src/handlers/cost.ts +77 -92
  35. package/src/handlers/decisions.test.ts +3 -2
  36. package/src/handlers/decisions.ts +32 -27
  37. package/src/handlers/deployment.ts +142 -190
  38. package/src/handlers/discovery.test.ts +4 -5
  39. package/src/handlers/discovery.ts +37 -6
  40. package/src/handlers/fallback.ts +31 -29
  41. package/src/handlers/file-checkouts.test.ts +477 -0
  42. package/src/handlers/file-checkouts.ts +127 -0
  43. package/src/handlers/findings.test.ts +145 -0
  44. package/src/handlers/findings.ts +101 -64
  45. package/src/handlers/git-issues.ts +40 -80
  46. package/src/handlers/ideas.ts +56 -54
  47. package/src/handlers/index.ts +6 -0
  48. package/src/handlers/milestones.test.ts +1 -1
  49. package/src/handlers/milestones.ts +47 -45
  50. package/src/handlers/organizations.ts +104 -129
  51. package/src/handlers/progress.ts +24 -22
  52. package/src/handlers/project.ts +89 -57
  53. package/src/handlers/requests.ts +18 -14
  54. package/src/handlers/roles.test.ts +303 -0
  55. package/src/handlers/roles.ts +208 -0
  56. package/src/handlers/session.ts +39 -17
  57. package/src/handlers/sprints.ts +96 -129
  58. package/src/handlers/tasks.ts +144 -138
  59. package/src/handlers/validation.test.ts +1 -1
  60. package/src/handlers/validation.ts +20 -22
  61. package/src/tools.ts +387 -0
  62. package/dist/config/tool-categories.d.ts +0 -31
  63. package/dist/config/tool-categories.js +0 -253
  64. package/dist/knowledge.d.ts +0 -6
  65. package/dist/knowledge.js +0 -218
@@ -6,12 +6,23 @@
6
6
  * - claim_validation
7
7
  * - validate_task
8
8
  */
9
- import { validateRequired, validateUUID } from '../validators.js';
9
+ import { parseArgs, uuidValidator } from '../validators.js';
10
10
  import { getApiClient } from '../api-client.js';
11
- export const getTasksAwaitingValidation = async (args, ctx) => {
12
- const { project_id } = args;
13
- validateRequired(project_id, 'project_id');
14
- validateUUID(project_id, 'project_id');
11
+ // Argument schemas for type-safe parsing
12
+ const getTasksAwaitingValidationSchema = {
13
+ project_id: { type: 'string', required: true, validate: uuidValidator },
14
+ };
15
+ const claimValidationSchema = {
16
+ task_id: { type: 'string', required: true, validate: uuidValidator },
17
+ };
18
+ const validateTaskSchema = {
19
+ task_id: { type: 'string', required: true, validate: uuidValidator },
20
+ approved: { type: 'boolean', required: true },
21
+ validation_notes: { type: 'string' },
22
+ skip_pr_check: { type: 'boolean' },
23
+ };
24
+ export const getTasksAwaitingValidation = async (args, _ctx) => {
25
+ const { project_id } = parseArgs(args, getTasksAwaitingValidationSchema);
15
26
  const apiClient = getApiClient();
16
27
  const response = await apiClient.getTasksAwaitingValidation(project_id);
17
28
  if (!response.ok) {
@@ -20,9 +31,7 @@ export const getTasksAwaitingValidation = async (args, ctx) => {
20
31
  return { result: response.data };
21
32
  };
22
33
  export const claimValidation = async (args, ctx) => {
23
- const { task_id } = args;
24
- validateRequired(task_id, 'task_id');
25
- validateUUID(task_id, 'task_id');
34
+ const { task_id } = parseArgs(args, claimValidationSchema);
26
35
  const { session } = ctx;
27
36
  const currentSessionId = session.currentSessionId;
28
37
  const apiClient = getApiClient();
@@ -33,12 +42,7 @@ export const claimValidation = async (args, ctx) => {
33
42
  return { result: response.data };
34
43
  };
35
44
  export const validateTask = async (args, ctx) => {
36
- const { task_id, validation_notes, approved, skip_pr_check } = args;
37
- validateRequired(task_id, 'task_id');
38
- validateUUID(task_id, 'task_id');
39
- if (approved === undefined) {
40
- throw new Error('approved is required');
41
- }
45
+ const { task_id, approved, validation_notes, skip_pr_check } = parseArgs(args, validateTaskSchema);
42
46
  const { session } = ctx;
43
47
  const currentSessionId = session.currentSessionId;
44
48
  const apiClient = getApiClient();
package/dist/tools.js CHANGED
@@ -2525,4 +2525,391 @@ Only returns tasks where all dependencies are completed.`,
2525
2525
  required: ['project_id'],
2526
2526
  },
2527
2527
  },
2528
+ // ============================================================================
2529
+ // Sprint Tools
2530
+ // ============================================================================
2531
+ {
2532
+ name: 'create_sprint',
2533
+ description: `Create a new sprint. Sprints are time-bounded bodies of work with velocity tracking.
2534
+ Sprints start in 'planning' status where tasks can be added with story points.`,
2535
+ inputSchema: {
2536
+ type: 'object',
2537
+ properties: {
2538
+ project_id: {
2539
+ type: 'string',
2540
+ description: 'Project UUID',
2541
+ },
2542
+ title: {
2543
+ type: 'string',
2544
+ description: 'Sprint title (e.g., "Sprint 5" or "Q1 Release")',
2545
+ },
2546
+ goal: {
2547
+ type: 'string',
2548
+ description: 'Sprint goal statement',
2549
+ },
2550
+ start_date: {
2551
+ type: 'string',
2552
+ description: 'Start date (YYYY-MM-DD)',
2553
+ },
2554
+ end_date: {
2555
+ type: 'string',
2556
+ description: 'End date (YYYY-MM-DD)',
2557
+ },
2558
+ auto_deploy_on_completion: {
2559
+ type: 'boolean',
2560
+ description: 'Automatically request deployment when sprint completes (default: false)',
2561
+ },
2562
+ deploy_environment: {
2563
+ type: 'string',
2564
+ enum: ['development', 'staging', 'production'],
2565
+ description: 'Target environment for auto-deploy (default: production)',
2566
+ },
2567
+ deploy_version_bump: {
2568
+ type: 'string',
2569
+ enum: ['patch', 'minor', 'major'],
2570
+ description: 'Version bump for auto-deploy (default: minor)',
2571
+ },
2572
+ },
2573
+ required: ['project_id', 'title', 'start_date', 'end_date'],
2574
+ },
2575
+ },
2576
+ {
2577
+ name: 'update_sprint',
2578
+ description: `Update a sprint's details. Can update title, goal, dates, and deployment settings.`,
2579
+ inputSchema: {
2580
+ type: 'object',
2581
+ properties: {
2582
+ sprint_id: {
2583
+ type: 'string',
2584
+ description: 'Sprint UUID',
2585
+ },
2586
+ title: {
2587
+ type: 'string',
2588
+ description: 'New sprint title',
2589
+ },
2590
+ goal: {
2591
+ type: 'string',
2592
+ description: 'New sprint goal',
2593
+ },
2594
+ start_date: {
2595
+ type: 'string',
2596
+ description: 'New start date (YYYY-MM-DD)',
2597
+ },
2598
+ end_date: {
2599
+ type: 'string',
2600
+ description: 'New end date (YYYY-MM-DD)',
2601
+ },
2602
+ auto_deploy_on_completion: {
2603
+ type: 'boolean',
2604
+ description: 'Auto-deploy setting',
2605
+ },
2606
+ deploy_environment: {
2607
+ type: 'string',
2608
+ enum: ['development', 'staging', 'production'],
2609
+ description: 'Target environment',
2610
+ },
2611
+ deploy_version_bump: {
2612
+ type: 'string',
2613
+ enum: ['patch', 'minor', 'major'],
2614
+ description: 'Version bump type',
2615
+ },
2616
+ },
2617
+ required: ['sprint_id'],
2618
+ },
2619
+ },
2620
+ {
2621
+ name: 'get_sprint',
2622
+ description: `Get a sprint with all its tasks organized by phase (pre/core/post).
2623
+ Includes progress percentage, velocity points, and committed points.
2624
+ Use summary_only: true to get task counts and next task instead of full task arrays (saves tokens).`,
2625
+ inputSchema: {
2626
+ type: 'object',
2627
+ properties: {
2628
+ sprint_id: {
2629
+ type: 'string',
2630
+ description: 'Sprint UUID',
2631
+ },
2632
+ summary_only: {
2633
+ type: 'boolean',
2634
+ description: 'Return task counts and next task instead of full task arrays (default: false)',
2635
+ },
2636
+ },
2637
+ required: ['sprint_id'],
2638
+ },
2639
+ },
2640
+ {
2641
+ name: 'get_sprints',
2642
+ description: `List sprints for a project with velocity metrics.
2643
+ Returns sprints sorted by sprint_number descending (most recent first).`,
2644
+ inputSchema: {
2645
+ type: 'object',
2646
+ properties: {
2647
+ project_id: {
2648
+ type: 'string',
2649
+ description: 'Project UUID',
2650
+ },
2651
+ status: {
2652
+ type: 'string',
2653
+ enum: ['planning', 'active', 'in_review', 'retrospective', 'completed', 'cancelled'],
2654
+ description: 'Filter by sprint status (optional)',
2655
+ },
2656
+ limit: {
2657
+ type: 'number',
2658
+ description: 'Max sprints to return (default: 20, max: 100)',
2659
+ },
2660
+ },
2661
+ required: ['project_id'],
2662
+ },
2663
+ },
2664
+ {
2665
+ name: 'delete_sprint',
2666
+ description: `Delete a sprint. Tasks are preserved but no longer grouped.`,
2667
+ inputSchema: {
2668
+ type: 'object',
2669
+ properties: {
2670
+ sprint_id: {
2671
+ type: 'string',
2672
+ description: 'Sprint UUID',
2673
+ },
2674
+ },
2675
+ required: ['sprint_id'],
2676
+ },
2677
+ },
2678
+ {
2679
+ name: 'start_sprint',
2680
+ description: `Start a sprint. Transitions from 'planning' to 'active' status.
2681
+ Locks the committed_points at the current total story points.`,
2682
+ inputSchema: {
2683
+ type: 'object',
2684
+ properties: {
2685
+ sprint_id: {
2686
+ type: 'string',
2687
+ description: 'Sprint UUID',
2688
+ },
2689
+ },
2690
+ required: ['sprint_id'],
2691
+ },
2692
+ },
2693
+ {
2694
+ name: 'complete_sprint',
2695
+ description: `Complete a sprint. Handles retrospective phase and auto-deployment if configured.
2696
+ Status flow: active → in_review → retrospective → completed`,
2697
+ inputSchema: {
2698
+ type: 'object',
2699
+ properties: {
2700
+ sprint_id: {
2701
+ type: 'string',
2702
+ description: 'Sprint UUID',
2703
+ },
2704
+ retrospective_notes: {
2705
+ type: 'string',
2706
+ description: 'Sprint retrospective notes',
2707
+ },
2708
+ skip_retrospective: {
2709
+ type: 'boolean',
2710
+ description: 'Skip retrospective phase and go directly to completed (default: false)',
2711
+ },
2712
+ },
2713
+ required: ['sprint_id'],
2714
+ },
2715
+ },
2716
+ {
2717
+ name: 'add_task_to_sprint',
2718
+ description: `Add a task to a sprint with optional story points.
2719
+ Tasks can be added during 'planning' status. Story points contribute to committed_points.`,
2720
+ inputSchema: {
2721
+ type: 'object',
2722
+ properties: {
2723
+ sprint_id: {
2724
+ type: 'string',
2725
+ description: 'Sprint UUID',
2726
+ },
2727
+ task_id: {
2728
+ type: 'string',
2729
+ description: 'Task UUID to add',
2730
+ },
2731
+ story_points: {
2732
+ type: 'number',
2733
+ description: 'Story point estimate (optional, must be non-negative integer)',
2734
+ },
2735
+ phase: {
2736
+ type: 'string',
2737
+ enum: ['pre', 'core', 'post'],
2738
+ description: 'Task phase (default: core)',
2739
+ },
2740
+ },
2741
+ required: ['sprint_id', 'task_id'],
2742
+ },
2743
+ },
2744
+ {
2745
+ name: 'remove_task_from_sprint',
2746
+ description: `Remove a task from a sprint. Task is preserved but returns to backlog.`,
2747
+ inputSchema: {
2748
+ type: 'object',
2749
+ properties: {
2750
+ sprint_id: {
2751
+ type: 'string',
2752
+ description: 'Sprint UUID',
2753
+ },
2754
+ task_id: {
2755
+ type: 'string',
2756
+ description: 'Task UUID to remove',
2757
+ },
2758
+ },
2759
+ required: ['sprint_id', 'task_id'],
2760
+ },
2761
+ },
2762
+ {
2763
+ name: 'get_sprint_backlog',
2764
+ description: `Get tasks from backlog/pending that can be added to a sprint.
2765
+ Returns tasks not already assigned to any body of work or sprint.`,
2766
+ inputSchema: {
2767
+ type: 'object',
2768
+ properties: {
2769
+ project_id: {
2770
+ type: 'string',
2771
+ description: 'Project UUID',
2772
+ },
2773
+ sprint_id: {
2774
+ type: 'string',
2775
+ description: 'Sprint UUID to exclude already-added tasks (optional)',
2776
+ },
2777
+ },
2778
+ required: ['project_id'],
2779
+ },
2780
+ },
2781
+ {
2782
+ name: 'get_sprint_velocity',
2783
+ description: `Get velocity metrics for completed sprints.
2784
+ Returns committed vs completed points and average velocity.`,
2785
+ inputSchema: {
2786
+ type: 'object',
2787
+ properties: {
2788
+ project_id: {
2789
+ type: 'string',
2790
+ description: 'Project UUID',
2791
+ },
2792
+ limit: {
2793
+ type: 'number',
2794
+ description: 'Number of sprints to analyze (default: 10, max: 50)',
2795
+ },
2796
+ },
2797
+ required: ['project_id'],
2798
+ },
2799
+ },
2800
+ // ============================================================================
2801
+ // Git Issue Tools
2802
+ // ============================================================================
2803
+ {
2804
+ name: 'add_git_issue',
2805
+ description: `Record a git-related issue (merge conflict, push failure, etc.). Auto-created by claim_validation when conflicts detected.`,
2806
+ inputSchema: {
2807
+ type: 'object',
2808
+ properties: {
2809
+ project_id: {
2810
+ type: 'string',
2811
+ description: 'Project UUID',
2812
+ },
2813
+ issue_type: {
2814
+ type: 'string',
2815
+ enum: ['merge_conflict', 'push_failed', 'rebase_needed', 'branch_diverged', 'pr_not_mergeable'],
2816
+ description: 'Type of git issue',
2817
+ },
2818
+ branch: {
2819
+ type: 'string',
2820
+ description: 'Branch where the issue occurred',
2821
+ },
2822
+ target_branch: {
2823
+ type: 'string',
2824
+ description: 'Target branch for merge/rebase (optional)',
2825
+ },
2826
+ pr_url: {
2827
+ type: 'string',
2828
+ description: 'Pull request URL if applicable (optional)',
2829
+ },
2830
+ conflicting_files: {
2831
+ type: 'array',
2832
+ items: { type: 'string' },
2833
+ description: 'List of files with conflicts (optional)',
2834
+ },
2835
+ error_message: {
2836
+ type: 'string',
2837
+ description: 'Error message from git operation (optional)',
2838
+ },
2839
+ task_id: {
2840
+ type: 'string',
2841
+ description: 'Related task UUID (optional)',
2842
+ },
2843
+ },
2844
+ required: ['project_id', 'issue_type', 'branch'],
2845
+ },
2846
+ },
2847
+ {
2848
+ name: 'resolve_git_issue',
2849
+ description: `Mark a git issue as resolved.`,
2850
+ inputSchema: {
2851
+ type: 'object',
2852
+ properties: {
2853
+ git_issue_id: {
2854
+ type: 'string',
2855
+ description: 'Git issue UUID',
2856
+ },
2857
+ resolution_note: {
2858
+ type: 'string',
2859
+ description: 'How the issue was resolved (optional)',
2860
+ },
2861
+ auto_resolved: {
2862
+ type: 'boolean',
2863
+ description: 'Whether this was auto-resolved (e.g., PR became mergeable)',
2864
+ },
2865
+ },
2866
+ required: ['git_issue_id'],
2867
+ },
2868
+ },
2869
+ {
2870
+ name: 'get_git_issues',
2871
+ description: `Get git issues for a project, optionally filtered by status, type, or branch.`,
2872
+ inputSchema: {
2873
+ type: 'object',
2874
+ properties: {
2875
+ project_id: {
2876
+ type: 'string',
2877
+ description: 'Project UUID',
2878
+ },
2879
+ status: {
2880
+ type: 'string',
2881
+ enum: ['open', 'resolved'],
2882
+ description: 'Filter by status (default: open)',
2883
+ },
2884
+ issue_type: {
2885
+ type: 'string',
2886
+ enum: ['merge_conflict', 'push_failed', 'rebase_needed', 'branch_diverged', 'pr_not_mergeable'],
2887
+ description: 'Filter by issue type (optional)',
2888
+ },
2889
+ branch: {
2890
+ type: 'string',
2891
+ description: 'Filter by branch (optional)',
2892
+ },
2893
+ limit: {
2894
+ type: 'number',
2895
+ description: 'Max issues to return (default: 50)',
2896
+ },
2897
+ },
2898
+ required: ['project_id'],
2899
+ },
2900
+ },
2901
+ {
2902
+ name: 'delete_git_issue',
2903
+ description: `Delete a git issue.`,
2904
+ inputSchema: {
2905
+ type: 'object',
2906
+ properties: {
2907
+ git_issue_id: {
2908
+ type: 'string',
2909
+ description: 'Git issue UUID',
2910
+ },
2911
+ },
2912
+ required: ['git_issue_id'],
2913
+ },
2914
+ },
2528
2915
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibescope/mcp-server",
3
- "version": "0.2.0",
3
+ "version": "0.2.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
@@ -47,7 +47,8 @@ export class VibescopeApiClient {
47
47
  return {
48
48
  ok: false,
49
49
  status: response.status,
50
- error: data.error || `HTTP ${response.status}`
50
+ error: data.error || `HTTP ${response.status}`,
51
+ data // Include full response data for additional error context
51
52
  };
52
53
  }
53
54
 
@@ -306,6 +307,7 @@ export class VibescopeApiClient {
306
307
  estimated_minutes?: number;
307
308
  blocking?: boolean;
308
309
  session_id?: string;
310
+ task_type?: string;
309
311
  }): Promise<ApiResponse<{
310
312
  success: boolean;
311
313
  task_id: string;
@@ -539,7 +541,11 @@ export class VibescopeApiClient {
539
541
  // ============================================================================
540
542
  // Decision endpoints
541
543
  // ============================================================================
542
- async getDecisions(projectId: string): Promise<ApiResponse<{
544
+ async getDecisions(projectId: string, options?: {
545
+ limit?: number;
546
+ offset?: number;
547
+ search_query?: string;
548
+ }): Promise<ApiResponse<{
543
549
  decisions: Array<{
544
550
  id: string;
545
551
  title: string;
@@ -549,7 +555,7 @@ export class VibescopeApiClient {
549
555
  created_at: string;
550
556
  }>;
551
557
  }>> {
552
- return this.proxy('get_decisions', { project_id: projectId });
558
+ return this.proxy('get_decisions', { project_id: projectId, ...options });
553
559
  }
554
560
 
555
561
  async logDecision(projectId: string, params: {
@@ -1005,6 +1011,8 @@ export class VibescopeApiClient {
1005
1011
  async getActivityFeed(projectId: string, params?: {
1006
1012
  limit?: number;
1007
1013
  since?: string;
1014
+ types?: string[];
1015
+ created_by?: string;
1008
1016
  }): Promise<ApiResponse<{
1009
1017
  activities: Array<{
1010
1018
  type: string;
@@ -1139,14 +1147,17 @@ export class VibescopeApiClient {
1139
1147
  // Knowledge base endpoint
1140
1148
  // ============================================================================
1141
1149
  async queryKnowledgeBase(projectId: string, params?: {
1150
+ scope?: 'summary' | 'detailed';
1142
1151
  categories?: string[];
1143
1152
  limit?: number;
1144
1153
  search_query?: string;
1145
1154
  }): Promise<ApiResponse<{
1146
- findings?: Array<{ id: string; title: string; category: string; severity: string }>;
1147
- decisions?: Array<{ id: string; title: string; description: string }>;
1148
- completed_tasks?: Array<{ id: string; title: string; completed_at: string }>;
1155
+ findings?: Array<{ id: string; title: string; category: string; severity: string; description?: string }>;
1156
+ decisions?: Array<{ id: string; title: string; description: string; rationale?: string }>;
1157
+ completed_tasks?: Array<{ id: string; title: string; completed_at: string; summary?: string }>;
1149
1158
  resolved_blockers?: Array<{ id: string; description: string; resolution_note?: string }>;
1159
+ progress?: Array<{ id: string; summary: string; details?: string }>;
1160
+ qa?: Array<{ id: string; question: string; answer: string }>;
1150
1161
  }>> {
1151
1162
  return this.proxy('query_knowledge_base', {
1152
1163
  project_id: projectId,
@@ -1800,6 +1811,78 @@ export class VibescopeApiClient {
1800
1811
  }>>> {
1801
1812
  return this.proxy('get_help_topics', {});
1802
1813
  }
1814
+
1815
+ // ============================================================================
1816
+ // File Checkout endpoints (multi-agent coordination)
1817
+ // ============================================================================
1818
+ async checkoutFile(projectId: string, filePath: string, reason?: string, sessionId?: string): Promise<ApiResponse<{
1819
+ success: boolean;
1820
+ checkout_id: string;
1821
+ file_path: string;
1822
+ already_checked_out?: boolean;
1823
+ message: string;
1824
+ }>> {
1825
+ return this.proxy('checkout_file', {
1826
+ project_id: projectId,
1827
+ file_path: filePath,
1828
+ reason
1829
+ }, sessionId ? {
1830
+ session_id: sessionId,
1831
+ persona: null,
1832
+ instance_id: ''
1833
+ } : undefined);
1834
+ }
1835
+
1836
+ async checkinFile(params: {
1837
+ checkout_id?: string;
1838
+ project_id?: string;
1839
+ file_path?: string;
1840
+ summary?: string;
1841
+ }, sessionId?: string): Promise<ApiResponse<{
1842
+ success: boolean;
1843
+ checkout_id: string;
1844
+ message: string;
1845
+ }>> {
1846
+ return this.proxy('checkin_file', params, sessionId ? {
1847
+ session_id: sessionId,
1848
+ persona: null,
1849
+ instance_id: ''
1850
+ } : undefined);
1851
+ }
1852
+
1853
+ async getFileCheckouts(projectId: string, options?: {
1854
+ status?: string;
1855
+ file_path?: string;
1856
+ limit?: number;
1857
+ }): Promise<ApiResponse<{
1858
+ checkouts: Array<{
1859
+ id: string;
1860
+ file_path: string;
1861
+ status: string;
1862
+ checked_out_at: string;
1863
+ checkout_reason?: string;
1864
+ checked_in_at?: string;
1865
+ checkin_summary?: string;
1866
+ checked_out_by?: string;
1867
+ }>;
1868
+ }>> {
1869
+ return this.proxy('get_file_checkouts', {
1870
+ project_id: projectId,
1871
+ ...options
1872
+ });
1873
+ }
1874
+
1875
+ async abandonCheckout(params: {
1876
+ checkout_id?: string;
1877
+ project_id?: string;
1878
+ file_path?: string;
1879
+ }): Promise<ApiResponse<{
1880
+ success: boolean;
1881
+ checkout_id: string;
1882
+ message: string;
1883
+ }>> {
1884
+ return this.proxy('abandon_checkout', params);
1885
+ }
1803
1886
  }
1804
1887
 
1805
1888
  // Singleton instance
@@ -80,6 +80,7 @@ export const mockApiClient = {
80
80
  getFindingsStats: vi.fn(),
81
81
  updateFinding: vi.fn(),
82
82
  deleteFinding: vi.fn(),
83
+ queryKnowledgeBase: vi.fn(),
83
84
 
84
85
  // Requests
85
86
  getPendingRequests: vi.fn(),
@@ -169,6 +170,12 @@ export const mockApiClient = {
169
170
  getHelpTopic: vi.fn(),
170
171
  getHelpTopics: vi.fn(),
171
172
 
173
+ // File Checkouts
174
+ checkoutFile: vi.fn(),
175
+ checkinFile: vi.fn(),
176
+ getFileCheckouts: vi.fn(),
177
+ abandonCheckout: vi.fn(),
178
+
172
179
  // Proxy (generic)
173
180
  proxy: vi.fn(),
174
181
  };