@azerate/claudette-mcp 1.3.0 → 1.5.0
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/README.md +155 -17
- package/dist/index.js +570 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
# Claudette MCP Server
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
MCP server for Claudette IDE - providing Claude with comprehensive workspace management tools.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx @azerate/claudette-mcp
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or install globally:
|
|
12
|
+
```bash
|
|
13
|
+
npm install -g @azerate/claudette-mcp
|
|
14
|
+
```
|
|
8
15
|
|
|
9
16
|
## Setup
|
|
10
17
|
|
|
11
18
|
### Option 1: Add via Claude Code CLI
|
|
12
19
|
```bash
|
|
13
|
-
claude mcp add claudette
|
|
20
|
+
claude mcp add claudette -- npx @azerate/claudette-mcp
|
|
14
21
|
```
|
|
15
22
|
|
|
16
23
|
### Option 2: Add to .mcp.json (project-level)
|
|
@@ -20,29 +27,160 @@ Create `.mcp.json` in your project root:
|
|
|
20
27
|
"mcpServers": {
|
|
21
28
|
"claudette": {
|
|
22
29
|
"type": "stdio",
|
|
23
|
-
"command": "
|
|
24
|
-
"args": ["
|
|
30
|
+
"command": "npx",
|
|
31
|
+
"args": ["@azerate/claudette-mcp"]
|
|
25
32
|
}
|
|
26
33
|
}
|
|
27
34
|
}
|
|
28
35
|
```
|
|
29
36
|
|
|
30
37
|
### Option 3: Add to Claude Code settings
|
|
31
|
-
Add to `~/.claude.json
|
|
38
|
+
Add to `~/.claude.json`:
|
|
32
39
|
```json
|
|
33
40
|
"mcpServers": {
|
|
34
41
|
"claudette": {
|
|
35
42
|
"type": "stdio",
|
|
36
|
-
"command": "
|
|
37
|
-
"args": ["
|
|
43
|
+
"command": "npx",
|
|
44
|
+
"args": ["@azerate/claudette-mcp"]
|
|
38
45
|
}
|
|
39
46
|
}
|
|
40
47
|
```
|
|
41
48
|
|
|
42
|
-
##
|
|
49
|
+
## Available Tools
|
|
50
|
+
|
|
51
|
+
### Code Quality
|
|
52
|
+
|
|
53
|
+
| Tool | Description |
|
|
54
|
+
|------|-------------|
|
|
55
|
+
| `get_errors` | Get TypeScript compilation errors for the workspace |
|
|
56
|
+
| `run_tests` | Run Jest tests and return results |
|
|
57
|
+
| `get_test_results` | Get the latest test results |
|
|
58
|
+
| `run_benchmarks` | Run performance benchmarks (tinybench/vitest) |
|
|
59
|
+
| `get_benchmark_results` | Get the latest benchmark results |
|
|
60
|
+
|
|
61
|
+
### Git & Changes
|
|
62
|
+
|
|
63
|
+
| Tool | Description |
|
|
64
|
+
|------|-------------|
|
|
65
|
+
| `get_changes` | Get pending git changes (modified, added, deleted files) |
|
|
66
|
+
| `get_branch_info` | Get current branch, behind/ahead status, sync state |
|
|
67
|
+
| `create_branch` | Create a new feature branch from main/master |
|
|
68
|
+
| `sync_branch` | Rebase or merge current branch with main |
|
|
69
|
+
| `get_checkpoints` | List saved checkpoints (git stash snapshots) |
|
|
70
|
+
| `create_checkpoint` | Create a checkpoint before risky changes |
|
|
71
|
+
| `restore_checkpoint` | Restore workspace to a previous checkpoint |
|
|
72
|
+
| `delete_checkpoint` | Delete a checkpoint permanently |
|
|
73
|
+
|
|
74
|
+
### Workflow Automation
|
|
75
|
+
|
|
76
|
+
| Tool | Description |
|
|
77
|
+
|------|-------------|
|
|
78
|
+
| `get_workflow_status` | Get current workflow pipeline status |
|
|
79
|
+
| `trigger_workflow` | Start the workflow (lint, types, tests, coverage, benchmarks) |
|
|
80
|
+
| `generate_commit_message` | Generate a commit message from changes |
|
|
81
|
+
| `approve_commit` | Stage and commit with the provided message |
|
|
82
|
+
| `approve_push` | Push committed changes to remote |
|
|
83
|
+
| `approve_write_tests` | Mark the write tests step as complete |
|
|
84
|
+
| `approve_code_review` | Mark the code review step as complete |
|
|
85
|
+
|
|
86
|
+
### Project Memory
|
|
87
|
+
|
|
88
|
+
| Tool | Description |
|
|
89
|
+
|------|-------------|
|
|
90
|
+
| `get_memory` | Get project memory notes |
|
|
91
|
+
| `add_memory` | Add a note to project memory |
|
|
92
|
+
| `clear_memory` | Clear all project memory notes |
|
|
93
|
+
| `delete_memory` | Delete specific notes by index |
|
|
94
|
+
| `replace_memory` | Replace all memory with new notes |
|
|
95
|
+
|
|
96
|
+
### Scripts & Automation
|
|
97
|
+
|
|
98
|
+
| Tool | Description |
|
|
99
|
+
|------|-------------|
|
|
100
|
+
| `list_scripts` | List npm scripts and their status |
|
|
101
|
+
| `run_script` | Start an npm script |
|
|
102
|
+
| `stop_script` | Stop a running script |
|
|
103
|
+
| `get_console_output` | Get console output from a script |
|
|
104
|
+
| `check_quick_actions` | Check for pending UI-triggered actions |
|
|
105
|
+
|
|
106
|
+
### Refactoring
|
|
107
|
+
|
|
108
|
+
| Tool | Description |
|
|
109
|
+
|------|-------------|
|
|
110
|
+
| `create_refactor_plan` | Analyze workspace and create refactoring plan |
|
|
111
|
+
| `get_refactor_plan` | Get the current refactor plan |
|
|
112
|
+
| `get_next_refactor_step` | Get the next uncompleted step |
|
|
113
|
+
| `verify_refactor` | Run tests and compare to baseline |
|
|
114
|
+
| `complete_refactor_step` | Mark a step as completed |
|
|
115
|
+
| `complete_refactor` | Finish refactoring and delete plan |
|
|
116
|
+
|
|
117
|
+
## Workflow Pipeline
|
|
118
|
+
|
|
119
|
+
The workflow feature provides a 10-step guided development process with best-practice Git support:
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
trigger_workflow()
|
|
123
|
+
|
|
|
124
|
+
v
|
|
125
|
+
[AUTOMATIC CHECKS]
|
|
126
|
+
1. Type checking (tsc --noEmit)
|
|
127
|
+
2. Lint/Format (eslint --fix)
|
|
128
|
+
3. Run tests
|
|
129
|
+
4. Coverage analysis (files needing tests)
|
|
130
|
+
5. Benchmarks (optional)
|
|
131
|
+
|
|
|
132
|
+
v
|
|
133
|
+
[HUMAN GATES]
|
|
134
|
+
6. Write Tests (if coverage found gaps)
|
|
135
|
+
7. Commit (approve_commit)
|
|
136
|
+
8. Push (approve_push)
|
|
137
|
+
9. Create PR (skipped if on main)
|
|
138
|
+
10. Code Review (approve_code_review)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Branch Management
|
|
142
|
+
|
|
143
|
+
Best practice: Work on feature branches, not directly on main.
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
# Check current branch status
|
|
147
|
+
get_branch_info(workspace_path="/path/to/project")
|
|
148
|
+
|
|
149
|
+
# Create a feature branch
|
|
150
|
+
create_branch(workspace_path="/path/to/project", branch_name="feature/my-feature")
|
|
151
|
+
|
|
152
|
+
# Sync with latest main (rebase)
|
|
153
|
+
sync_branch(workspace_path="/path/to/project", method="rebase")
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
The workflow enforces feature branch usage by default (`requireFeatureBranch: true`).
|
|
157
|
+
Toggle this in the UI or set in `.claudette/workflow-config.json`.
|
|
158
|
+
|
|
159
|
+
## Example Usage
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
# Check for errors
|
|
163
|
+
get_errors(workspace_path="/path/to/project")
|
|
164
|
+
|
|
165
|
+
# Run full workflow
|
|
166
|
+
trigger_workflow(workspace_path="/path/to/project")
|
|
167
|
+
|
|
168
|
+
# Check workflow status
|
|
169
|
+
get_workflow_status(workspace_path="/path/to/project")
|
|
170
|
+
|
|
171
|
+
# After checks pass, commit
|
|
172
|
+
generate_commit_message(workspace_path="/path/to/project")
|
|
173
|
+
approve_commit(workspace_path="/path/to/project", message="Add new feature")
|
|
174
|
+
|
|
175
|
+
# Push changes
|
|
176
|
+
approve_push(workspace_path="/path/to/project")
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Requirements
|
|
180
|
+
|
|
181
|
+
- Node.js 18+
|
|
182
|
+
- Claudette IDE server running on port 52001 (for full functionality)
|
|
183
|
+
|
|
184
|
+
## License
|
|
43
185
|
|
|
44
|
-
|
|
45
|
-
- `get_errors` - Pass workspace_path to check for TypeScript errors
|
|
46
|
-
- `get_changes` - Pass workspace_path to see git status
|
|
47
|
-
- `get_memory` - Pass workspace_path to read project notes
|
|
48
|
-
- `add_memory` - Pass workspace_path and note to save a note
|
|
186
|
+
MIT
|
package/dist/index.js
CHANGED
|
@@ -419,6 +419,199 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
419
419
|
required: ["workspace_path"],
|
|
420
420
|
},
|
|
421
421
|
},
|
|
422
|
+
{
|
|
423
|
+
name: "run_benchmarks",
|
|
424
|
+
description: "Run performance benchmarks for the workspace. Returns benchmark results with ops/sec and timing data. Supports Tinybench, Vitest bench, and Benchmark.js.",
|
|
425
|
+
inputSchema: {
|
|
426
|
+
type: "object",
|
|
427
|
+
properties: {
|
|
428
|
+
workspace_path: {
|
|
429
|
+
type: "string",
|
|
430
|
+
description: "Path to the workspace directory",
|
|
431
|
+
},
|
|
432
|
+
},
|
|
433
|
+
required: ["workspace_path"],
|
|
434
|
+
},
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
name: "get_benchmark_results",
|
|
438
|
+
description: "Get the latest benchmark results for the workspace. Shows ops/sec, timing, and comparison data.",
|
|
439
|
+
inputSchema: {
|
|
440
|
+
type: "object",
|
|
441
|
+
properties: {
|
|
442
|
+
workspace_path: {
|
|
443
|
+
type: "string",
|
|
444
|
+
description: "Path to the workspace directory",
|
|
445
|
+
},
|
|
446
|
+
},
|
|
447
|
+
required: ["workspace_path"],
|
|
448
|
+
},
|
|
449
|
+
},
|
|
450
|
+
{
|
|
451
|
+
name: "get_workflow_status",
|
|
452
|
+
description: "Get the current workflow status for the workspace. Shows which checks have run (lint, types, tests, coverage, benchmarks) and git action status (commit, push, PR).",
|
|
453
|
+
inputSchema: {
|
|
454
|
+
type: "object",
|
|
455
|
+
properties: {
|
|
456
|
+
workspace_path: {
|
|
457
|
+
type: "string",
|
|
458
|
+
description: "Path to the workspace directory",
|
|
459
|
+
},
|
|
460
|
+
},
|
|
461
|
+
required: ["workspace_path"],
|
|
462
|
+
},
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
name: "trigger_workflow",
|
|
466
|
+
description: "Start the development workflow pipeline. Runs automatic checks: lint (with auto-fix), type checking, tests, coverage analysis, and optionally benchmarks. The workflow pauses at git actions (commit, push, PR) for user approval.",
|
|
467
|
+
inputSchema: {
|
|
468
|
+
type: "object",
|
|
469
|
+
properties: {
|
|
470
|
+
workspace_path: {
|
|
471
|
+
type: "string",
|
|
472
|
+
description: "Path to the workspace directory",
|
|
473
|
+
},
|
|
474
|
+
},
|
|
475
|
+
required: ["workspace_path"],
|
|
476
|
+
},
|
|
477
|
+
},
|
|
478
|
+
{
|
|
479
|
+
name: "generate_commit_message",
|
|
480
|
+
description: "Generate a commit message based on the current git changes. Returns a suggested commit message.",
|
|
481
|
+
inputSchema: {
|
|
482
|
+
type: "object",
|
|
483
|
+
properties: {
|
|
484
|
+
workspace_path: {
|
|
485
|
+
type: "string",
|
|
486
|
+
description: "Path to the workspace directory",
|
|
487
|
+
},
|
|
488
|
+
},
|
|
489
|
+
required: ["workspace_path"],
|
|
490
|
+
},
|
|
491
|
+
},
|
|
492
|
+
{
|
|
493
|
+
name: "approve_commit",
|
|
494
|
+
description: "Stage all changes and create a git commit with the provided message. Use after workflow checks pass.",
|
|
495
|
+
inputSchema: {
|
|
496
|
+
type: "object",
|
|
497
|
+
properties: {
|
|
498
|
+
workspace_path: {
|
|
499
|
+
type: "string",
|
|
500
|
+
description: "Path to the workspace directory",
|
|
501
|
+
},
|
|
502
|
+
message: {
|
|
503
|
+
type: "string",
|
|
504
|
+
description: "The commit message",
|
|
505
|
+
},
|
|
506
|
+
},
|
|
507
|
+
required: ["workspace_path", "message"],
|
|
508
|
+
},
|
|
509
|
+
},
|
|
510
|
+
{
|
|
511
|
+
name: "approve_push",
|
|
512
|
+
description: "Push the committed changes to the remote repository.",
|
|
513
|
+
inputSchema: {
|
|
514
|
+
type: "object",
|
|
515
|
+
properties: {
|
|
516
|
+
workspace_path: {
|
|
517
|
+
type: "string",
|
|
518
|
+
description: "Path to the workspace directory",
|
|
519
|
+
},
|
|
520
|
+
},
|
|
521
|
+
required: ["workspace_path"],
|
|
522
|
+
},
|
|
523
|
+
},
|
|
524
|
+
{
|
|
525
|
+
name: "approve_write_tests",
|
|
526
|
+
description: "Mark the write tests step as complete after tests have been written for uncovered files.",
|
|
527
|
+
inputSchema: {
|
|
528
|
+
type: "object",
|
|
529
|
+
properties: {
|
|
530
|
+
workspace_path: {
|
|
531
|
+
type: "string",
|
|
532
|
+
description: "Path to the workspace directory",
|
|
533
|
+
},
|
|
534
|
+
tests_written: {
|
|
535
|
+
type: "number",
|
|
536
|
+
description: "Number of test files written",
|
|
537
|
+
},
|
|
538
|
+
},
|
|
539
|
+
required: ["workspace_path", "tests_written"],
|
|
540
|
+
},
|
|
541
|
+
},
|
|
542
|
+
{
|
|
543
|
+
name: "approve_code_review",
|
|
544
|
+
description: "Mark the code review step as complete after the PR has been reviewed and approved.",
|
|
545
|
+
inputSchema: {
|
|
546
|
+
type: "object",
|
|
547
|
+
properties: {
|
|
548
|
+
workspace_path: {
|
|
549
|
+
type: "string",
|
|
550
|
+
description: "Path to the workspace directory",
|
|
551
|
+
},
|
|
552
|
+
reviewer: {
|
|
553
|
+
type: "string",
|
|
554
|
+
description: "Name of the reviewer (optional)",
|
|
555
|
+
},
|
|
556
|
+
},
|
|
557
|
+
required: ["workspace_path"],
|
|
558
|
+
},
|
|
559
|
+
},
|
|
560
|
+
{
|
|
561
|
+
name: "get_branch_info",
|
|
562
|
+
description: "Get current git branch information including branch name, whether it's main/master, and behind/ahead counts relative to origin and main branch.",
|
|
563
|
+
inputSchema: {
|
|
564
|
+
type: "object",
|
|
565
|
+
properties: {
|
|
566
|
+
workspace_path: {
|
|
567
|
+
type: "string",
|
|
568
|
+
description: "Path to the workspace directory",
|
|
569
|
+
},
|
|
570
|
+
fetch: {
|
|
571
|
+
type: "boolean",
|
|
572
|
+
description: "Whether to fetch from remote first (slower but more accurate). Default: false",
|
|
573
|
+
},
|
|
574
|
+
},
|
|
575
|
+
required: ["workspace_path"],
|
|
576
|
+
},
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
name: "create_branch",
|
|
580
|
+
description: "Create a new feature branch from main/master. Best practice: always create feature branches for new work instead of committing directly to main.",
|
|
581
|
+
inputSchema: {
|
|
582
|
+
type: "object",
|
|
583
|
+
properties: {
|
|
584
|
+
workspace_path: {
|
|
585
|
+
type: "string",
|
|
586
|
+
description: "Path to the workspace directory",
|
|
587
|
+
},
|
|
588
|
+
branch_name: {
|
|
589
|
+
type: "string",
|
|
590
|
+
description: "Name for the new branch (e.g., 'feature/add-login', 'fix/button-alignment')",
|
|
591
|
+
},
|
|
592
|
+
},
|
|
593
|
+
required: ["workspace_path", "branch_name"],
|
|
594
|
+
},
|
|
595
|
+
},
|
|
596
|
+
{
|
|
597
|
+
name: "sync_branch",
|
|
598
|
+
description: "Sync current branch with main/master by rebasing or merging. Use when your branch is behind main to incorporate latest changes.",
|
|
599
|
+
inputSchema: {
|
|
600
|
+
type: "object",
|
|
601
|
+
properties: {
|
|
602
|
+
workspace_path: {
|
|
603
|
+
type: "string",
|
|
604
|
+
description: "Path to the workspace directory",
|
|
605
|
+
},
|
|
606
|
+
method: {
|
|
607
|
+
type: "string",
|
|
608
|
+
enum: ["rebase", "merge"],
|
|
609
|
+
description: "Sync method: 'rebase' (cleaner history, default) or 'merge' (preserves branch history)",
|
|
610
|
+
},
|
|
611
|
+
},
|
|
612
|
+
required: ["workspace_path"],
|
|
613
|
+
},
|
|
614
|
+
},
|
|
422
615
|
],
|
|
423
616
|
};
|
|
424
617
|
});
|
|
@@ -1012,6 +1205,383 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1012
1205
|
return { content: [{ type: "text", text: `Error getting test results: ${err.message}` }] };
|
|
1013
1206
|
}
|
|
1014
1207
|
}
|
|
1208
|
+
case "run_benchmarks": {
|
|
1209
|
+
const workspacePath = args?.workspace_path;
|
|
1210
|
+
if (!workspacePath) {
|
|
1211
|
+
return { content: [{ type: "text", text: "Error: workspace_path is required" }] };
|
|
1212
|
+
}
|
|
1213
|
+
try {
|
|
1214
|
+
// Start the benchmarks
|
|
1215
|
+
const response = await fetch(`${CLAUDETTE_API}/api/benchmarks/run`, {
|
|
1216
|
+
method: "POST",
|
|
1217
|
+
headers: { "Content-Type": "application/json" },
|
|
1218
|
+
body: JSON.stringify({ path: workspacePath, async: false }),
|
|
1219
|
+
});
|
|
1220
|
+
const data = await response.json();
|
|
1221
|
+
if (!data.success) {
|
|
1222
|
+
return { content: [{ type: "text", text: `Failed to run benchmarks: ${data.error || data.results?.error}` }] };
|
|
1223
|
+
}
|
|
1224
|
+
const results = data.results;
|
|
1225
|
+
let output = `Benchmark Results\n${"=".repeat(50)}\n\n`;
|
|
1226
|
+
output += `Framework: ${results.framework}\n`;
|
|
1227
|
+
output += `Total Benchmarks: ${results.totalBenchmarks}\n`;
|
|
1228
|
+
output += `Duration: ${(results.duration / 1000).toFixed(2)}s\n\n`;
|
|
1229
|
+
if (results.suites && results.suites.length > 0) {
|
|
1230
|
+
for (const suite of results.suites) {
|
|
1231
|
+
output += `📦 ${suite.name}\n`;
|
|
1232
|
+
for (const bench of suite.benchmarks) {
|
|
1233
|
+
const opsFormatted = bench.opsPerSecond >= 1e6
|
|
1234
|
+
? `${(bench.opsPerSecond / 1e6).toFixed(2)}M`
|
|
1235
|
+
: bench.opsPerSecond >= 1e3
|
|
1236
|
+
? `${(bench.opsPerSecond / 1e3).toFixed(2)}K`
|
|
1237
|
+
: bench.opsPerSecond.toFixed(2);
|
|
1238
|
+
output += ` ⚡ ${bench.name}: ${opsFormatted} ops/s (±${bench.margin.toFixed(1)}%)\n`;
|
|
1239
|
+
}
|
|
1240
|
+
output += '\n';
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
return { content: [{ type: "text", text: output }] };
|
|
1244
|
+
}
|
|
1245
|
+
catch (err) {
|
|
1246
|
+
return { content: [{ type: "text", text: `Error running benchmarks: ${err.message}` }] };
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
case "get_benchmark_results": {
|
|
1250
|
+
const workspacePath = args?.workspace_path;
|
|
1251
|
+
if (!workspacePath) {
|
|
1252
|
+
return { content: [{ type: "text", text: "Error: workspace_path is required" }] };
|
|
1253
|
+
}
|
|
1254
|
+
try {
|
|
1255
|
+
const response = await fetch(`${CLAUDETTE_API}/api/benchmarks/status?path=${encodeURIComponent(workspacePath)}`);
|
|
1256
|
+
const status = await response.json();
|
|
1257
|
+
if (status.isRunning) {
|
|
1258
|
+
return { content: [{ type: "text", text: "Benchmarks are currently running..." }] };
|
|
1259
|
+
}
|
|
1260
|
+
if (!status.lastResult) {
|
|
1261
|
+
return { content: [{ type: "text", text: "No benchmark results found. Run benchmarks first with run_benchmarks." }] };
|
|
1262
|
+
}
|
|
1263
|
+
const results = status.lastResult;
|
|
1264
|
+
let output = `Benchmark Results\n${"=".repeat(50)}\n\n`;
|
|
1265
|
+
output += `Framework: ${results.framework}\n`;
|
|
1266
|
+
output += `Status: ${results.success ? "✅ SUCCESS" : "❌ FAILED"}\n`;
|
|
1267
|
+
output += `Total Benchmarks: ${results.totalBenchmarks}\n`;
|
|
1268
|
+
output += `Duration: ${(results.duration / 1000).toFixed(2)}s\n`;
|
|
1269
|
+
output += `Timestamp: ${results.timestamp}\n\n`;
|
|
1270
|
+
if (results.error) {
|
|
1271
|
+
output += `Error: ${results.error}\n\n`;
|
|
1272
|
+
}
|
|
1273
|
+
if (results.suites && results.suites.length > 0) {
|
|
1274
|
+
output += `Benchmark Details:\n${"─".repeat(40)}\n`;
|
|
1275
|
+
for (const suite of results.suites) {
|
|
1276
|
+
output += `\n📦 ${suite.name} (${suite.benchmarks.length} benchmarks)\n`;
|
|
1277
|
+
for (const bench of suite.benchmarks) {
|
|
1278
|
+
const opsFormatted = bench.opsPerSecond >= 1e6
|
|
1279
|
+
? `${(bench.opsPerSecond / 1e6).toFixed(2)}M`
|
|
1280
|
+
: bench.opsPerSecond >= 1e3
|
|
1281
|
+
? `${(bench.opsPerSecond / 1e3).toFixed(2)}K`
|
|
1282
|
+
: bench.opsPerSecond.toFixed(2);
|
|
1283
|
+
output += ` ⚡ ${bench.name}\n`;
|
|
1284
|
+
output += ` ${opsFormatted} ops/s | avg: ${bench.avgTime.toFixed(4)}ms | ±${bench.margin.toFixed(1)}%\n`;
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
return { content: [{ type: "text", text: output }] };
|
|
1289
|
+
}
|
|
1290
|
+
catch (err) {
|
|
1291
|
+
return { content: [{ type: "text", text: `Error getting benchmark results: ${err.message}` }] };
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
case "get_workflow_status": {
|
|
1295
|
+
const workspacePath = args?.workspace_path;
|
|
1296
|
+
if (!workspacePath) {
|
|
1297
|
+
return { content: [{ type: "text", text: "Error: workspace_path is required" }] };
|
|
1298
|
+
}
|
|
1299
|
+
try {
|
|
1300
|
+
const response = await fetch(`${CLAUDETTE_API}/api/workflow/status?path=${encodeURIComponent(workspacePath)}`);
|
|
1301
|
+
const status = await response.json();
|
|
1302
|
+
let output = `Workflow Status\n${"=".repeat(50)}\n\n`;
|
|
1303
|
+
output += `Current Step: ${status.currentStep}\n`;
|
|
1304
|
+
output += `Running: ${status.isRunning ? "Yes" : "No"}\n`;
|
|
1305
|
+
output += `Changed Files: ${status.changedFiles?.length || 0}\n\n`;
|
|
1306
|
+
output += `Automatic Checks:\n${"─".repeat(40)}\n`;
|
|
1307
|
+
const checkSteps = ['lint', 'types', 'tests', 'coverage', 'benchmarks'];
|
|
1308
|
+
for (const step of checkSteps) {
|
|
1309
|
+
const result = status.steps[step];
|
|
1310
|
+
const icon = result.status === 'passed' ? '✅' :
|
|
1311
|
+
result.status === 'failed' ? '❌' :
|
|
1312
|
+
result.status === 'warning' ? '⚠️' :
|
|
1313
|
+
result.status === 'running' ? '🔄' :
|
|
1314
|
+
result.status === 'skipped' ? '⏭️' : '⏸️';
|
|
1315
|
+
let info = '';
|
|
1316
|
+
if (step === 'lint' && result.fixed)
|
|
1317
|
+
info = ` (${result.fixed} fixed)`;
|
|
1318
|
+
if (step === 'types' && result.typeErrors)
|
|
1319
|
+
info = ` (${result.typeErrors} errors)`;
|
|
1320
|
+
if (step === 'tests' && result.passed !== undefined)
|
|
1321
|
+
info = ` (${result.passed}/${result.total})`;
|
|
1322
|
+
if (step === 'coverage' && result.percent !== undefined)
|
|
1323
|
+
info = ` (${result.percent}%)`;
|
|
1324
|
+
output += `${icon} ${step}${info}\n`;
|
|
1325
|
+
}
|
|
1326
|
+
output += `\nGit Actions:\n${"─".repeat(40)}\n`;
|
|
1327
|
+
const gitSteps = ['commit', 'push', 'pr'];
|
|
1328
|
+
for (const step of gitSteps) {
|
|
1329
|
+
const result = status.steps[step];
|
|
1330
|
+
const icon = result.status === 'passed' ? '✅' :
|
|
1331
|
+
result.status === 'pending' ? '⏸️' : '❓';
|
|
1332
|
+
output += `${icon} ${step}\n`;
|
|
1333
|
+
}
|
|
1334
|
+
if (status.error) {
|
|
1335
|
+
output += `\n❌ Error: ${status.error}\n`;
|
|
1336
|
+
}
|
|
1337
|
+
return { content: [{ type: "text", text: output }] };
|
|
1338
|
+
}
|
|
1339
|
+
catch (err) {
|
|
1340
|
+
return { content: [{ type: "text", text: `Error getting workflow status: ${err.message}` }] };
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
case "trigger_workflow": {
|
|
1344
|
+
const workspacePath = args?.workspace_path;
|
|
1345
|
+
if (!workspacePath) {
|
|
1346
|
+
return { content: [{ type: "text", text: "Error: workspace_path is required" }] };
|
|
1347
|
+
}
|
|
1348
|
+
try {
|
|
1349
|
+
const response = await fetch(`${CLAUDETTE_API}/api/workflow/trigger`, {
|
|
1350
|
+
method: "POST",
|
|
1351
|
+
headers: { "Content-Type": "application/json" },
|
|
1352
|
+
body: JSON.stringify({ path: workspacePath }),
|
|
1353
|
+
});
|
|
1354
|
+
const status = await response.json();
|
|
1355
|
+
let output = `Workflow triggered successfully!\n\n`;
|
|
1356
|
+
output += `Current Step: ${status.currentStep}\n`;
|
|
1357
|
+
output += `Changed Files: ${status.changedFiles?.length || 0}\n\n`;
|
|
1358
|
+
output += `The workflow will run these checks automatically:\n`;
|
|
1359
|
+
output += `1. Lint (with auto-fix)\n`;
|
|
1360
|
+
output += `2. Type checking\n`;
|
|
1361
|
+
output += `3. Tests\n`;
|
|
1362
|
+
output += `4. Coverage analysis\n`;
|
|
1363
|
+
output += `5. Benchmarks (optional)\n\n`;
|
|
1364
|
+
output += `Use get_workflow_status to monitor progress.`;
|
|
1365
|
+
return { content: [{ type: "text", text: output }] };
|
|
1366
|
+
}
|
|
1367
|
+
catch (err) {
|
|
1368
|
+
return { content: [{ type: "text", text: `Error triggering workflow: ${err.message}` }] };
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
case "generate_commit_message": {
|
|
1372
|
+
const workspacePath = args?.workspace_path;
|
|
1373
|
+
if (!workspacePath) {
|
|
1374
|
+
return { content: [{ type: "text", text: "Error: workspace_path is required" }] };
|
|
1375
|
+
}
|
|
1376
|
+
try {
|
|
1377
|
+
const response = await fetch(`${CLAUDETTE_API}/api/workflow/commit-message?path=${encodeURIComponent(workspacePath)}`);
|
|
1378
|
+
const data = await response.json();
|
|
1379
|
+
return { content: [{ type: "text", text: `Suggested commit message:\n\n${data.message}` }] };
|
|
1380
|
+
}
|
|
1381
|
+
catch (err) {
|
|
1382
|
+
return { content: [{ type: "text", text: `Error generating commit message: ${err.message}` }] };
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
case "approve_commit": {
|
|
1386
|
+
const workspacePath = args?.workspace_path;
|
|
1387
|
+
const message = args?.message;
|
|
1388
|
+
if (!workspacePath) {
|
|
1389
|
+
return { content: [{ type: "text", text: "Error: workspace_path is required" }] };
|
|
1390
|
+
}
|
|
1391
|
+
if (!message) {
|
|
1392
|
+
return { content: [{ type: "text", text: "Error: message is required" }] };
|
|
1393
|
+
}
|
|
1394
|
+
try {
|
|
1395
|
+
const response = await fetch(`${CLAUDETTE_API}/api/workflow/commit`, {
|
|
1396
|
+
method: "POST",
|
|
1397
|
+
headers: { "Content-Type": "application/json" },
|
|
1398
|
+
body: JSON.stringify({ path: workspacePath, message }),
|
|
1399
|
+
});
|
|
1400
|
+
const result = await response.json();
|
|
1401
|
+
if (result.status === 'passed') {
|
|
1402
|
+
return { content: [{ type: "text", text: `✅ Commit created successfully!\n\nMessage: ${result.message}\nFiles committed: ${result.filesCommitted}` }] };
|
|
1403
|
+
}
|
|
1404
|
+
else {
|
|
1405
|
+
return { content: [{ type: "text", text: `❌ Commit failed: ${result.error}` }] };
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
catch (err) {
|
|
1409
|
+
return { content: [{ type: "text", text: `Error creating commit: ${err.message}` }] };
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
case "approve_push": {
|
|
1413
|
+
const workspacePath = args?.workspace_path;
|
|
1414
|
+
if (!workspacePath) {
|
|
1415
|
+
return { content: [{ type: "text", text: "Error: workspace_path is required" }] };
|
|
1416
|
+
}
|
|
1417
|
+
try {
|
|
1418
|
+
const response = await fetch(`${CLAUDETTE_API}/api/workflow/push`, {
|
|
1419
|
+
method: "POST",
|
|
1420
|
+
headers: { "Content-Type": "application/json" },
|
|
1421
|
+
body: JSON.stringify({ path: workspacePath }),
|
|
1422
|
+
});
|
|
1423
|
+
const result = await response.json();
|
|
1424
|
+
if (result.status === 'passed') {
|
|
1425
|
+
return { content: [{ type: "text", text: `✅ Push successful!\n\nBranch: ${result.branch}\nRemote: ${result.remote}` }] };
|
|
1426
|
+
}
|
|
1427
|
+
else {
|
|
1428
|
+
return { content: [{ type: "text", text: `❌ Push failed: ${result.error}` }] };
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
catch (err) {
|
|
1432
|
+
return { content: [{ type: "text", text: `Error pushing changes: ${err.message}` }] };
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
case "approve_write_tests": {
|
|
1436
|
+
const workspacePath = args?.workspace_path;
|
|
1437
|
+
const testsWritten = args?.tests_written;
|
|
1438
|
+
if (!workspacePath) {
|
|
1439
|
+
return { content: [{ type: "text", text: "Error: workspace_path is required" }] };
|
|
1440
|
+
}
|
|
1441
|
+
if (testsWritten === undefined) {
|
|
1442
|
+
return { content: [{ type: "text", text: "Error: tests_written is required" }] };
|
|
1443
|
+
}
|
|
1444
|
+
try {
|
|
1445
|
+
const response = await fetch(`${CLAUDETTE_API}/api/workflow/write-tests`, {
|
|
1446
|
+
method: "POST",
|
|
1447
|
+
headers: { "Content-Type": "application/json" },
|
|
1448
|
+
body: JSON.stringify({ path: workspacePath, testsWritten }),
|
|
1449
|
+
});
|
|
1450
|
+
const result = await response.json();
|
|
1451
|
+
if (result.status === 'passed') {
|
|
1452
|
+
return { content: [{ type: "text", text: `✅ Write tests step complete!\n\nTests written: ${result.testsWritten}\n\nWorkflow advanced to commit stage.` }] };
|
|
1453
|
+
}
|
|
1454
|
+
else {
|
|
1455
|
+
return { content: [{ type: "text", text: `❌ Failed: ${result.error}` }] };
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
catch (err) {
|
|
1459
|
+
return { content: [{ type: "text", text: `Error: ${err.message}` }] };
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
case "approve_code_review": {
|
|
1463
|
+
const workspacePath = args?.workspace_path;
|
|
1464
|
+
const reviewer = args?.reviewer;
|
|
1465
|
+
if (!workspacePath) {
|
|
1466
|
+
return { content: [{ type: "text", text: "Error: workspace_path is required" }] };
|
|
1467
|
+
}
|
|
1468
|
+
try {
|
|
1469
|
+
const response = await fetch(`${CLAUDETTE_API}/api/workflow/code-review`, {
|
|
1470
|
+
method: "POST",
|
|
1471
|
+
headers: { "Content-Type": "application/json" },
|
|
1472
|
+
body: JSON.stringify({ path: workspacePath, reviewer }),
|
|
1473
|
+
});
|
|
1474
|
+
const result = await response.json();
|
|
1475
|
+
if (result.status === 'passed') {
|
|
1476
|
+
return { content: [{ type: "text", text: `✅ Code review approved!\n\n${result.reviewer ? `Reviewer: ${result.reviewer}\n` : ''}Workflow complete.` }] };
|
|
1477
|
+
}
|
|
1478
|
+
else {
|
|
1479
|
+
return { content: [{ type: "text", text: `❌ Failed: ${result.error}` }] };
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
catch (err) {
|
|
1483
|
+
return { content: [{ type: "text", text: `Error: ${err.message}` }] };
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
case "get_branch_info": {
|
|
1487
|
+
const workspacePath = args?.workspace_path;
|
|
1488
|
+
const doFetch = args?.fetch ?? false;
|
|
1489
|
+
if (!workspacePath) {
|
|
1490
|
+
return { content: [{ type: "text", text: "Error: workspace_path is required" }] };
|
|
1491
|
+
}
|
|
1492
|
+
try {
|
|
1493
|
+
const response = await fetch(`${CLAUDETTE_API}/api/workflow/branch?path=${encodeURIComponent(workspacePath)}&fetch=${doFetch}`);
|
|
1494
|
+
const info = await response.json();
|
|
1495
|
+
let output = `Branch Info\n${'='.repeat(50)}\n\n`;
|
|
1496
|
+
output += `Current Branch: ${info.current}\n`;
|
|
1497
|
+
output += `Is Main/Master: ${info.isMain ? 'Yes' : 'No'}\n`;
|
|
1498
|
+
output += `Main Branch: ${info.mainBranch}\n`;
|
|
1499
|
+
output += `Has Remote Tracking: ${info.hasRemote ? 'Yes' : 'No'}\n`;
|
|
1500
|
+
if (!info.isMain) {
|
|
1501
|
+
output += `\nSync Status:\n`;
|
|
1502
|
+
output += `────────────────────────────────────────\n`;
|
|
1503
|
+
if (info.behindMain > 0) {
|
|
1504
|
+
output += `⚠️ Behind ${info.mainBranch}: ${info.behindMain} commit(s)\n`;
|
|
1505
|
+
output += ` Run sync_branch to update\n`;
|
|
1506
|
+
}
|
|
1507
|
+
else {
|
|
1508
|
+
output += `✅ Up to date with ${info.mainBranch}\n`;
|
|
1509
|
+
}
|
|
1510
|
+
}
|
|
1511
|
+
if (info.hasRemote) {
|
|
1512
|
+
output += `\nRemote Status:\n`;
|
|
1513
|
+
output += `────────────────────────────────────────\n`;
|
|
1514
|
+
if (info.behindRemote > 0) {
|
|
1515
|
+
output += `⚠️ Behind origin: ${info.behindRemote} commit(s) - pull needed\n`;
|
|
1516
|
+
}
|
|
1517
|
+
if (info.aheadRemote > 0) {
|
|
1518
|
+
output += `📤 Ahead of origin: ${info.aheadRemote} commit(s) - push needed\n`;
|
|
1519
|
+
}
|
|
1520
|
+
if (info.behindRemote === 0 && info.aheadRemote === 0) {
|
|
1521
|
+
output += `✅ In sync with origin\n`;
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1524
|
+
if (info.isMain) {
|
|
1525
|
+
output += `\n⚠️ Best Practice: Create a feature branch instead of committing to ${info.mainBranch}\n`;
|
|
1526
|
+
output += ` Use create_branch to start a new feature branch\n`;
|
|
1527
|
+
}
|
|
1528
|
+
return { content: [{ type: "text", text: output }] };
|
|
1529
|
+
}
|
|
1530
|
+
catch (err) {
|
|
1531
|
+
return { content: [{ type: "text", text: `Error: ${err.message}` }] };
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
case "create_branch": {
|
|
1535
|
+
const workspacePath = args?.workspace_path;
|
|
1536
|
+
const branchName = args?.branch_name;
|
|
1537
|
+
if (!workspacePath) {
|
|
1538
|
+
return { content: [{ type: "text", text: "Error: workspace_path is required" }] };
|
|
1539
|
+
}
|
|
1540
|
+
if (!branchName) {
|
|
1541
|
+
return { content: [{ type: "text", text: "Error: branch_name is required" }] };
|
|
1542
|
+
}
|
|
1543
|
+
try {
|
|
1544
|
+
const response = await fetch(`${CLAUDETTE_API}/api/workflow/branch`, {
|
|
1545
|
+
method: "POST",
|
|
1546
|
+
headers: { "Content-Type": "application/json" },
|
|
1547
|
+
body: JSON.stringify({ path: workspacePath, name: branchName }),
|
|
1548
|
+
});
|
|
1549
|
+
const result = await response.json();
|
|
1550
|
+
if (result.success) {
|
|
1551
|
+
return { content: [{ type: "text", text: `✅ Created and switched to branch: ${result.branch}\n\nYou can now make changes and commit to this branch.` }] };
|
|
1552
|
+
}
|
|
1553
|
+
else {
|
|
1554
|
+
return { content: [{ type: "text", text: `❌ Failed to create branch: ${result.error}` }] };
|
|
1555
|
+
}
|
|
1556
|
+
}
|
|
1557
|
+
catch (err) {
|
|
1558
|
+
return { content: [{ type: "text", text: `Error: ${err.message}` }] };
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
case "sync_branch": {
|
|
1562
|
+
const workspacePath = args?.workspace_path;
|
|
1563
|
+
const method = args?.method ?? 'rebase';
|
|
1564
|
+
if (!workspacePath) {
|
|
1565
|
+
return { content: [{ type: "text", text: "Error: workspace_path is required" }] };
|
|
1566
|
+
}
|
|
1567
|
+
try {
|
|
1568
|
+
const response = await fetch(`${CLAUDETTE_API}/api/workflow/sync`, {
|
|
1569
|
+
method: "POST",
|
|
1570
|
+
headers: { "Content-Type": "application/json" },
|
|
1571
|
+
body: JSON.stringify({ path: workspacePath, method }),
|
|
1572
|
+
});
|
|
1573
|
+
const result = await response.json();
|
|
1574
|
+
if (result.success) {
|
|
1575
|
+
return { content: [{ type: "text", text: `✅ Branch synced successfully using ${method}!\n\nYour branch is now up to date with main.` }] };
|
|
1576
|
+
}
|
|
1577
|
+
else {
|
|
1578
|
+
return { content: [{ type: "text", text: `❌ Sync failed: ${result.error}` }] };
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
catch (err) {
|
|
1582
|
+
return { content: [{ type: "text", text: `Error: ${err.message}` }] };
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1015
1585
|
default:
|
|
1016
1586
|
return { content: [{ type: "text", text: `Unknown tool: ${name}` }] };
|
|
1017
1587
|
}
|
package/package.json
CHANGED