@vibescope/mcp-server 0.2.2 → 0.2.4

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 (80) hide show
  1. package/CHANGELOG.md +84 -0
  2. package/README.md +35 -20
  3. package/dist/api-client.d.ts +276 -8
  4. package/dist/api-client.js +128 -9
  5. package/dist/handlers/blockers.d.ts +11 -0
  6. package/dist/handlers/blockers.js +37 -2
  7. package/dist/handlers/bodies-of-work.d.ts +2 -0
  8. package/dist/handlers/bodies-of-work.js +30 -1
  9. package/dist/handlers/connectors.js +2 -2
  10. package/dist/handlers/decisions.d.ts +11 -0
  11. package/dist/handlers/decisions.js +37 -2
  12. package/dist/handlers/deployment.d.ts +6 -0
  13. package/dist/handlers/deployment.js +33 -5
  14. package/dist/handlers/discovery.js +27 -11
  15. package/dist/handlers/fallback.js +12 -6
  16. package/dist/handlers/file-checkouts.d.ts +1 -0
  17. package/dist/handlers/file-checkouts.js +17 -2
  18. package/dist/handlers/findings.d.ts +5 -0
  19. package/dist/handlers/findings.js +19 -2
  20. package/dist/handlers/git-issues.js +4 -2
  21. package/dist/handlers/ideas.d.ts +5 -0
  22. package/dist/handlers/ideas.js +19 -2
  23. package/dist/handlers/progress.js +2 -2
  24. package/dist/handlers/project.d.ts +1 -0
  25. package/dist/handlers/project.js +35 -2
  26. package/dist/handlers/requests.js +6 -3
  27. package/dist/handlers/roles.js +13 -2
  28. package/dist/handlers/session.d.ts +12 -0
  29. package/dist/handlers/session.js +288 -25
  30. package/dist/handlers/sprints.d.ts +2 -0
  31. package/dist/handlers/sprints.js +30 -1
  32. package/dist/handlers/tasks.d.ts +25 -2
  33. package/dist/handlers/tasks.js +228 -35
  34. package/dist/handlers/tool-docs.js +72 -5
  35. package/dist/templates/agent-guidelines.d.ts +18 -0
  36. package/dist/templates/agent-guidelines.js +207 -0
  37. package/dist/tools.js +478 -125
  38. package/dist/utils.d.ts +5 -2
  39. package/dist/utils.js +90 -51
  40. package/package.json +51 -46
  41. package/scripts/version-bump.ts +203 -0
  42. package/src/api-client.test.ts +8 -3
  43. package/src/api-client.ts +376 -13
  44. package/src/handlers/__test-setup__.ts +5 -0
  45. package/src/handlers/blockers.test.ts +76 -0
  46. package/src/handlers/blockers.ts +56 -2
  47. package/src/handlers/bodies-of-work.ts +59 -1
  48. package/src/handlers/connectors.ts +2 -2
  49. package/src/handlers/decisions.test.ts +71 -2
  50. package/src/handlers/decisions.ts +56 -2
  51. package/src/handlers/deployment.test.ts +81 -0
  52. package/src/handlers/deployment.ts +38 -5
  53. package/src/handlers/discovery.ts +27 -11
  54. package/src/handlers/fallback.test.ts +11 -10
  55. package/src/handlers/fallback.ts +14 -8
  56. package/src/handlers/file-checkouts.test.ts +83 -3
  57. package/src/handlers/file-checkouts.ts +22 -2
  58. package/src/handlers/findings.test.ts +2 -2
  59. package/src/handlers/findings.ts +38 -2
  60. package/src/handlers/git-issues.test.ts +2 -2
  61. package/src/handlers/git-issues.ts +4 -2
  62. package/src/handlers/ideas.test.ts +1 -1
  63. package/src/handlers/ideas.ts +34 -2
  64. package/src/handlers/progress.ts +2 -2
  65. package/src/handlers/project.ts +47 -2
  66. package/src/handlers/requests.test.ts +38 -7
  67. package/src/handlers/requests.ts +6 -3
  68. package/src/handlers/roles.test.ts +1 -1
  69. package/src/handlers/roles.ts +20 -2
  70. package/src/handlers/session.test.ts +303 -4
  71. package/src/handlers/session.ts +335 -28
  72. package/src/handlers/sprints.ts +61 -1
  73. package/src/handlers/tasks.test.ts +0 -73
  74. package/src/handlers/tasks.ts +269 -40
  75. package/src/handlers/tool-docs.ts +77 -5
  76. package/src/handlers/types.test.ts +259 -0
  77. package/src/templates/agent-guidelines.ts +210 -0
  78. package/src/tools.ts +479 -125
  79. package/src/utils.test.ts +7 -5
  80. package/src/utils.ts +95 -51
package/dist/utils.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export declare const AGENT_PERSONAS: readonly ["Apex", "Arc", "Atlas", "Blaze", "Bolt", "Byte", "Cipher", "Core", "Dash", "Drift", "Echo", "Edge", "Ember", "Flux", "Forge", "Ghost", "Glitch", "Haze", "Hex", "Ion", "Iris", "Jade", "Jet", "Karma", "Kite", "Lux", "Mako", "Neon", "Nova", "Onyx", "Orbit", "Pixel", "Pulse", "Quest", "Rex", "Rune", "Shade", "Spark", "Storm", "Trace", "Turbo", "Vex", "Volt", "Warp", "Wave", "Zen", "Zero"];
1
+ export declare const AGENT_PERSONAS: readonly ["Yoda", "Leia", "Han", "Luke", "Rey", "Finn", "Kylo", "Mando", "Grogu", "Ahsoka", "Frodo", "Gandalf", "Aragorn", "Legolas", "Gimli", "Sam", "Bilbo", "Gollum", "Spock", "Kirk", "Picard", "Data", "Worf", "Seven", "Paul", "Chani", "Duncan", "Stilgar", "Leto", "Neo", "Trinity", "Morpheus", "Mal", "River", "Kaylee", "Wash", "Arya", "Tyrion", "Dany", "Bran", "Groot", "Rocket", "Gamora", "Drax", "Loki", "Thor", "Ripley", "Jarvis", "Cortana", "GLaDOS"];
2
2
  export type AgentPersona = typeof AGENT_PERSONAS[number];
3
3
  export declare const FALLBACK_ACTIVITIES: readonly [{
4
4
  readonly activity: "feature_ideation";
@@ -67,7 +67,10 @@ export type FallbackActivity = typeof FALLBACK_ACTIVITIES[number];
67
67
  */
68
68
  export declare function getRandomFallbackActivity(): FallbackActivity;
69
69
  /**
70
- * Select an available persona from the pool (randomly)
70
+ * Select an available persona from the pool
71
+ * Uses time-based seeding to ensure variety across sessions while maintaining
72
+ * determinism within the same minute (for retry consistency).
73
+ *
71
74
  * @param usedPersonas Set of personas currently in use
72
75
  * @param instanceId The instance ID for fallback naming
73
76
  * @returns The selected persona name
package/dist/utils.js CHANGED
@@ -3,56 +3,68 @@
3
3
  // ============================================================================
4
4
  // ============================================================================
5
5
  // Agent Persona Pool
6
- // Short, memorable names for distinguishing agents on the dashboard
6
+ // Iconic sci-fi & fantasy character names for agents on the dashboard
7
7
  // ============================================================================
8
8
  export const AGENT_PERSONAS = [
9
- 'Apex',
10
- 'Arc',
11
- 'Atlas',
12
- 'Blaze',
13
- 'Bolt',
14
- 'Byte',
15
- 'Cipher',
16
- 'Core',
17
- 'Dash',
18
- 'Drift',
19
- 'Echo',
20
- 'Edge',
21
- 'Ember',
22
- 'Flux',
23
- 'Forge',
24
- 'Ghost',
25
- 'Glitch',
26
- 'Haze',
27
- 'Hex',
28
- 'Ion',
29
- 'Iris',
30
- 'Jade',
31
- 'Jet',
32
- 'Karma',
33
- 'Kite',
34
- 'Lux',
35
- 'Mako',
36
- 'Neon',
37
- 'Nova',
38
- 'Onyx',
39
- 'Orbit',
40
- 'Pixel',
41
- 'Pulse',
42
- 'Quest',
43
- 'Rex',
44
- 'Rune',
45
- 'Shade',
46
- 'Spark',
47
- 'Storm',
48
- 'Trace',
49
- 'Turbo',
50
- 'Vex',
51
- 'Volt',
52
- 'Warp',
53
- 'Wave',
54
- 'Zen',
55
- 'Zero',
9
+ // Star Wars
10
+ 'Yoda',
11
+ 'Leia',
12
+ 'Han',
13
+ 'Luke',
14
+ 'Rey',
15
+ 'Finn',
16
+ 'Kylo',
17
+ 'Mando',
18
+ 'Grogu',
19
+ 'Ahsoka',
20
+ // Lord of the Rings
21
+ 'Frodo',
22
+ 'Gandalf',
23
+ 'Aragorn',
24
+ 'Legolas',
25
+ 'Gimli',
26
+ 'Sam',
27
+ 'Bilbo',
28
+ 'Gollum',
29
+ // Star Trek
30
+ 'Spock',
31
+ 'Kirk',
32
+ 'Picard',
33
+ 'Data',
34
+ 'Worf',
35
+ 'Seven',
36
+ // Dune
37
+ 'Paul',
38
+ 'Chani',
39
+ 'Duncan',
40
+ 'Stilgar',
41
+ 'Leto',
42
+ // The Matrix
43
+ 'Neo',
44
+ 'Trinity',
45
+ 'Morpheus',
46
+ // Firefly
47
+ 'Mal',
48
+ 'River',
49
+ 'Kaylee',
50
+ 'Wash',
51
+ // Game of Thrones
52
+ 'Arya',
53
+ 'Tyrion',
54
+ 'Dany',
55
+ 'Bran',
56
+ // Marvel / Guardians
57
+ 'Groot',
58
+ 'Rocket',
59
+ 'Gamora',
60
+ 'Drax',
61
+ 'Loki',
62
+ 'Thor',
63
+ // Classic Sci-Fi AIs & Characters
64
+ 'Ripley',
65
+ 'Jarvis',
66
+ 'Cortana',
67
+ 'GLaDOS',
56
68
  ];
57
69
  // ============================================================================
58
70
  // Fallback Activities for Idle Agents
@@ -151,7 +163,30 @@ export function getRandomFallbackActivity() {
151
163
  return FALLBACK_ACTIVITIES[index];
152
164
  }
153
165
  /**
154
- * Select an available persona from the pool (randomly)
166
+ * Fisher-Yates shuffle with a seed for reproducible randomness
167
+ */
168
+ function seededShuffle(array, seed) {
169
+ const result = [...array];
170
+ let currentSeed = seed;
171
+ // Simple seeded random number generator (mulberry32)
172
+ const random = () => {
173
+ currentSeed = (currentSeed + 0x6D2B79F5) | 0;
174
+ let t = currentSeed;
175
+ t = Math.imul(t ^ (t >>> 15), t | 1);
176
+ t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
177
+ return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
178
+ };
179
+ for (let i = result.length - 1; i > 0; i--) {
180
+ const j = Math.floor(random() * (i + 1));
181
+ [result[i], result[j]] = [result[j], result[i]];
182
+ }
183
+ return result;
184
+ }
185
+ /**
186
+ * Select an available persona from the pool
187
+ * Uses time-based seeding to ensure variety across sessions while maintaining
188
+ * determinism within the same minute (for retry consistency).
189
+ *
155
190
  * @param usedPersonas Set of personas currently in use
156
191
  * @param instanceId The instance ID for fallback naming
157
192
  * @returns The selected persona name
@@ -161,8 +196,12 @@ export function selectPersona(usedPersonas, instanceId) {
161
196
  if (availablePersonas.length === 0) {
162
197
  return `Agent-${instanceId.slice(0, 6)}`;
163
198
  }
164
- const randomIndex = Math.floor(Math.random() * availablePersonas.length);
165
- return availablePersonas[randomIndex];
199
+ // Use current minute as seed for variety, plus some randomness for the final pick
200
+ // This ensures different starting points each minute while allowing retries to work
201
+ const minuteSeed = Math.floor(Date.now() / 60000);
202
+ const shuffled = seededShuffle(availablePersonas, minuteSeed);
203
+ // Pick randomly from the shuffled list for additional variety
204
+ return shuffled[Math.floor(Math.random() * shuffled.length)];
166
205
  }
167
206
  export class RateLimiter {
168
207
  requests = new Map();
package/package.json CHANGED
@@ -1,46 +1,51 @@
1
- {
2
- "name": "@vibescope/mcp-server",
3
- "version": "0.2.2",
4
- "description": "MCP server for Vibescope - AI project tracking tools",
5
- "type": "module",
6
- "main": "dist/index.js",
7
- "types": "dist/index.d.ts",
8
- "bin": {
9
- "vibescope-mcp": "dist/index.js",
10
- "vibescope-cli": "dist/cli.js"
11
- },
12
- "repository": {
13
- "type": "git",
14
- "url": "https://github.com/Nonatomic/Vibescope.git",
15
- "directory": "packages/mcp-server"
16
- },
17
- "publishConfig": {
18
- "access": "public"
19
- },
20
- "scripts": {
21
- "build": "tsc",
22
- "dev": "tsc --watch",
23
- "test": "vitest run",
24
- "test:watch": "vitest",
25
- "docs:generate": "npx tsx scripts/generate-docs.ts --output=docs/TOOLS.md",
26
- "docs:preview": "npx tsx scripts/generate-docs.ts",
27
- "prepublishOnly": "npm run build"
28
- },
29
- "keywords": [
30
- "mcp",
31
- "model-context-protocol",
32
- "vibescope",
33
- "ai",
34
- "project-management"
35
- ],
36
- "license": "MIT",
37
- "devDependencies": {
38
- "@types/node": "^22.10.0",
39
- "tsx": "^4.7.0",
40
- "typescript": "^5.7.0",
41
- "vitest": "^4.0.17"
42
- },
43
- "dependencies": {
44
- "@modelcontextprotocol/sdk": "^1.25.2"
45
- }
46
- }
1
+ {
2
+ "name": "@vibescope/mcp-server",
3
+ "version": "0.2.4",
4
+ "description": "MCP server for Vibescope - AI project tracking tools",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bin": {
9
+ "vibescope-mcp": "dist/index.js",
10
+ "vibescope-cli": "dist/cli.js"
11
+ },
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "https://github.com/Nonatomic/Vibescope.git",
15
+ "directory": "packages/mcp-server"
16
+ },
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "scripts": {
21
+ "build": "tsc",
22
+ "dev": "tsc --watch",
23
+ "test": "vitest run",
24
+ "test:watch": "vitest",
25
+ "docs:generate": "npx tsx scripts/generate-docs.ts --output=docs/TOOLS.md",
26
+ "docs:preview": "npx tsx scripts/generate-docs.ts",
27
+ "version:check": "npx tsx scripts/version-bump.ts --dry-run",
28
+ "version:bump": "npx tsx scripts/version-bump.ts",
29
+ "version:patch": "npx tsx scripts/version-bump.ts --patch",
30
+ "version:minor": "npx tsx scripts/version-bump.ts --minor",
31
+ "version:major": "npx tsx scripts/version-bump.ts --major",
32
+ "prepublishOnly": "npm run build"
33
+ },
34
+ "keywords": [
35
+ "mcp",
36
+ "model-context-protocol",
37
+ "vibescope",
38
+ "ai",
39
+ "project-management"
40
+ ],
41
+ "license": "MIT",
42
+ "devDependencies": {
43
+ "@types/node": "^22.10.0",
44
+ "tsx": "^4.7.0",
45
+ "typescript": "^5.7.0",
46
+ "vitest": "^4.0.17"
47
+ },
48
+ "dependencies": {
49
+ "@modelcontextprotocol/sdk": "^1.25.2"
50
+ }
51
+ }
@@ -0,0 +1,203 @@
1
+ #!/usr/bin/env npx tsx
2
+ /**
3
+ * Automatic Semantic Version Bumping Script
4
+ *
5
+ * Analyzes git commit messages since the last version tag to determine
6
+ * the appropriate version bump based on conventional commits.
7
+ *
8
+ * Patterns:
9
+ * - `feat!:` or `BREAKING CHANGE:` → major bump
10
+ * - `feat:` or `feat(scope):` → minor bump
11
+ * - `fix:` or `fix(scope):` → patch bump
12
+ * - `docs:`, `chore:`, `style:`, `refactor:`, `test:` → patch bump (if any fix/feat)
13
+ *
14
+ * Usage:
15
+ * npx tsx scripts/version-bump.ts [--dry-run] [--major|--minor|--patch]
16
+ *
17
+ * Options:
18
+ * --dry-run Show what would be done without making changes
19
+ * --major Force a major version bump
20
+ * --minor Force a minor version bump
21
+ * --patch Force a patch version bump
22
+ */
23
+
24
+ import { execSync } from 'child_process';
25
+ import { readFileSync, writeFileSync } from 'fs';
26
+ import { resolve, dirname } from 'path';
27
+ import { fileURLToPath } from 'url';
28
+
29
+ const __dirname = dirname(fileURLToPath(import.meta.url));
30
+ const packageJsonPath = resolve(__dirname, '../package.json');
31
+
32
+ interface PackageJson {
33
+ version: string;
34
+ [key: string]: unknown;
35
+ }
36
+
37
+ type BumpType = 'major' | 'minor' | 'patch' | 'none';
38
+
39
+ function parseArgs(): { dryRun: boolean; forceBump: BumpType | null } {
40
+ const args = process.argv.slice(2);
41
+ const dryRun = args.includes('--dry-run');
42
+
43
+ let forceBump: BumpType | null = null;
44
+ if (args.includes('--major')) forceBump = 'major';
45
+ else if (args.includes('--minor')) forceBump = 'minor';
46
+ else if (args.includes('--patch')) forceBump = 'patch';
47
+
48
+ return { dryRun, forceBump };
49
+ }
50
+
51
+ function getCurrentVersion(): string {
52
+ const packageJson: PackageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
53
+ return packageJson.version;
54
+ }
55
+
56
+ function getLastVersionTag(): string | null {
57
+ try {
58
+ // Get the latest tag that matches a version pattern (v*.*.* or *.*.*)
59
+ const tag = execSync('git describe --tags --abbrev=0 --match "v*" 2>/dev/null || git describe --tags --abbrev=0 --match "[0-9]*" 2>/dev/null', {
60
+ encoding: 'utf-8',
61
+ cwd: resolve(__dirname, '../../..')
62
+ }).trim();
63
+ return tag || null;
64
+ } catch {
65
+ return null;
66
+ }
67
+ }
68
+
69
+ function getCommitsSinceTag(tag: string | null): string[] {
70
+ try {
71
+ const range = tag ? `${tag}..HEAD` : 'HEAD';
72
+ const commits = execSync(`git log ${range} --pretty=format:"%s" -- packages/mcp-server`, {
73
+ encoding: 'utf-8',
74
+ cwd: resolve(__dirname, '../../..')
75
+ }).trim();
76
+ return commits ? commits.split('\n').filter(Boolean) : [];
77
+ } catch {
78
+ return [];
79
+ }
80
+ }
81
+
82
+ function analyzeCommits(commits: string[]): { bumpType: BumpType; reasons: string[] } {
83
+ const reasons: string[] = [];
84
+ let bumpType: BumpType = 'none';
85
+
86
+ for (const commit of commits) {
87
+ const lowerCommit = commit.toLowerCase();
88
+
89
+ // Check for breaking changes (major)
90
+ if (lowerCommit.includes('breaking change') || /^[a-z]+(\([^)]+\))?!:/.test(commit)) {
91
+ bumpType = 'major';
92
+ reasons.push(`BREAKING: ${commit}`);
93
+ }
94
+ // Check for features (minor) - only upgrade if not already major
95
+ else if (/^feat(\([^)]+\))?:/.test(commit)) {
96
+ if (bumpType !== 'major') {
97
+ bumpType = 'minor';
98
+ }
99
+ reasons.push(`Feature: ${commit}`);
100
+ }
101
+ // Check for fixes (patch) - only upgrade if still none
102
+ else if (/^fix(\([^)]+\))?:/.test(commit)) {
103
+ if (bumpType === 'none') {
104
+ bumpType = 'patch';
105
+ }
106
+ reasons.push(`Fix: ${commit}`);
107
+ }
108
+ // Other conventional commits that warrant a patch
109
+ else if (/^(docs|chore|style|refactor|test|perf|build|ci)(\([^)]+\))?:/.test(commit)) {
110
+ reasons.push(`Other: ${commit}`);
111
+ }
112
+ }
113
+
114
+ // If we have reasons but no bump type, default to patch
115
+ if (bumpType === 'none' && reasons.length > 0) {
116
+ bumpType = 'patch';
117
+ }
118
+
119
+ return { bumpType, reasons };
120
+ }
121
+
122
+ function bumpVersion(currentVersion: string, bumpType: BumpType): string {
123
+ const [major, minor, patch] = currentVersion.split('.').map(Number);
124
+
125
+ switch (bumpType) {
126
+ case 'major':
127
+ return `${major + 1}.0.0`;
128
+ case 'minor':
129
+ return `${major}.${minor + 1}.0`;
130
+ case 'patch':
131
+ return `${major}.${minor}.${patch + 1}`;
132
+ default:
133
+ return currentVersion;
134
+ }
135
+ }
136
+
137
+ function updatePackageJson(newVersion: string): void {
138
+ const packageJson: PackageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
139
+ packageJson.version = newVersion;
140
+ writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
141
+ }
142
+
143
+ function main(): void {
144
+ const { dryRun, forceBump } = parseArgs();
145
+
146
+ console.log('šŸ” Analyzing version bump for @vibescope/mcp-server...\n');
147
+
148
+ const currentVersion = getCurrentVersion();
149
+ console.log(`Current version: ${currentVersion}`);
150
+
151
+ const lastTag = getLastVersionTag();
152
+ console.log(`Last version tag: ${lastTag || '(none found)'}`);
153
+
154
+ const commits = getCommitsSinceTag(lastTag);
155
+ console.log(`Commits to analyze: ${commits.length}\n`);
156
+
157
+ let bumpType: BumpType;
158
+ let reasons: string[];
159
+
160
+ if (forceBump) {
161
+ bumpType = forceBump;
162
+ reasons = [`Forced ${forceBump} bump via command line`];
163
+ console.log(`⚔ Forcing ${forceBump} version bump\n`);
164
+ } else {
165
+ const analysis = analyzeCommits(commits);
166
+ bumpType = analysis.bumpType;
167
+ reasons = analysis.reasons;
168
+
169
+ if (reasons.length > 0) {
170
+ console.log('šŸ“ Relevant commits:');
171
+ for (const reason of reasons.slice(0, 10)) {
172
+ console.log(` - ${reason}`);
173
+ }
174
+ if (reasons.length > 10) {
175
+ console.log(` ... and ${reasons.length - 10} more`);
176
+ }
177
+ console.log();
178
+ }
179
+ }
180
+
181
+ if (bumpType === 'none') {
182
+ console.log('āœ… No version bump needed - no relevant changes detected.');
183
+ return;
184
+ }
185
+
186
+ const newVersion = bumpVersion(currentVersion, bumpType);
187
+ console.log(`šŸ“¦ Version bump: ${currentVersion} → ${newVersion} (${bumpType})`);
188
+
189
+ if (dryRun) {
190
+ console.log('\nšŸ”ø Dry run - no changes made.');
191
+ return;
192
+ }
193
+
194
+ updatePackageJson(newVersion);
195
+ console.log(`\nāœ… Updated package.json to version ${newVersion}`);
196
+ console.log('\nNext steps:');
197
+ console.log(' 1. Review the changes: git diff packages/mcp-server/package.json');
198
+ console.log(' 2. Commit: git add -A && git commit -m "chore(release): bump @vibescope/mcp-server to ' + newVersion + '"');
199
+ console.log(' 3. Create a tag: git tag -a v' + newVersion + ' -m "Release v' + newVersion + '"');
200
+ console.log(' 4. Push: git push && git push --tags');
201
+ }
202
+
203
+ main();
@@ -509,7 +509,7 @@ describe('VibescopeApiClient', () => {
509
509
  });
510
510
 
511
511
  describe('completeTask', () => {
512
- it('should call correct endpoint', async () => {
512
+ it('should call proxy endpoint', async () => {
513
513
  mockFetch.mockResolvedValue(
514
514
  createMockResponse({ success: true })
515
515
  );
@@ -518,12 +518,17 @@ describe('VibescopeApiClient', () => {
518
518
  summary: 'Task completed successfully',
519
519
  });
520
520
 
521
+ // completeTask uses proxy endpoint for consistency (direct endpoint had Vercel routing issues)
521
522
  expect(mockFetch).toHaveBeenCalledWith(
522
- expect.stringContaining('/api/mcp/tasks/task-123/complete'),
523
+ expect.stringContaining('/api/mcp/proxy'),
523
524
  expect.objectContaining({
524
525
  method: 'POST',
525
526
  body: JSON.stringify({
526
- summary: 'Task completed successfully',
527
+ operation: 'complete_task',
528
+ args: {
529
+ task_id: 'task-123',
530
+ summary: 'Task completed successfully',
531
+ },
527
532
  }),
528
533
  })
529
534
  );