@azerate/claudette-mcp 1.5.0 → 1.7.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 +28 -0
- package/dist/index.js +175 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -64,6 +64,7 @@ Add to `~/.claude.json`:
|
|
|
64
64
|
|------|-------------|
|
|
65
65
|
| `get_changes` | Get pending git changes (modified, added, deleted files) |
|
|
66
66
|
| `get_branch_info` | Get current branch, behind/ahead status, sync state |
|
|
67
|
+
| `get_branch_pr_status` | Check if current branch has an open/merged/closed PR |
|
|
67
68
|
| `create_branch` | Create a new feature branch from main/master |
|
|
68
69
|
| `sync_branch` | Rebase or merge current branch with main |
|
|
69
70
|
| `get_checkpoints` | List saved checkpoints (git stash snapshots) |
|
|
@@ -76,11 +77,13 @@ Add to `~/.claude.json`:
|
|
|
76
77
|
| Tool | Description |
|
|
77
78
|
|------|-------------|
|
|
78
79
|
| `get_workflow_status` | Get current workflow pipeline status |
|
|
80
|
+
| `get_workflow_recommendation` | **Smart recommendation** - analyzes branch, PR status, and changes to suggest the best next action |
|
|
79
81
|
| `trigger_workflow` | Start the workflow (lint, types, tests, coverage, benchmarks) |
|
|
80
82
|
| `generate_commit_message` | Generate a commit message from changes |
|
|
81
83
|
| `approve_commit` | Stage and commit with the provided message |
|
|
82
84
|
| `approve_push` | Push committed changes to remote |
|
|
83
85
|
| `approve_write_tests` | Mark the write tests step as complete |
|
|
86
|
+
| `create_pr` | Create a pull request using gh CLI |
|
|
84
87
|
| `approve_code_review` | Mark the code review step as complete |
|
|
85
88
|
|
|
86
89
|
### Project Memory
|
|
@@ -114,6 +117,31 @@ Add to `~/.claude.json`:
|
|
|
114
117
|
| `complete_refactor_step` | Mark a step as completed |
|
|
115
118
|
| `complete_refactor` | Finish refactoring and delete plan |
|
|
116
119
|
|
|
120
|
+
## Smart Workflow Recommendations
|
|
121
|
+
|
|
122
|
+
Before starting a workflow, always call `get_workflow_recommendation` to get intelligent guidance:
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
get_workflow_recommendation(workspace_path="/path/to/project")
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The tool analyzes your current state and recommends the best action:
|
|
129
|
+
|
|
130
|
+
| Recommended Action | When | What to Do |
|
|
131
|
+
|-------------------|------|------------|
|
|
132
|
+
| `start_workflow` | Normal flow, no blockers | Proceed with `trigger_workflow` |
|
|
133
|
+
| `create_feature_branch` | On main with `requireFeatureBranch` enabled | Use `create_branch` first |
|
|
134
|
+
| `add_to_existing_pr` | On feature branch with open PR | Your commits will update the existing PR |
|
|
135
|
+
| `switch_to_main` | PR was merged, branch is stale | Switch to main, pull, create new branch |
|
|
136
|
+
| `create_new_branch` | PR was closed (not merged) | Create a fresh branch or reopen PR |
|
|
137
|
+
| `sync_branch_first` | Branch is >5 commits behind main | Use `sync_branch` before committing |
|
|
138
|
+
| `no_changes` | No uncommitted changes | Nothing to commit yet |
|
|
139
|
+
|
|
140
|
+
Each recommendation includes:
|
|
141
|
+
- **reason**: Why this action is recommended
|
|
142
|
+
- **suggestion**: What you should do (trust this!)
|
|
143
|
+
- **consequences**: What will happen if you proceed
|
|
144
|
+
|
|
117
145
|
## Workflow Pipeline
|
|
118
146
|
|
|
119
147
|
The workflow feature provides a 10-step guided development process with best-practice Git support:
|
package/dist/index.js
CHANGED
|
@@ -557,6 +557,28 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
557
557
|
required: ["workspace_path"],
|
|
558
558
|
},
|
|
559
559
|
},
|
|
560
|
+
{
|
|
561
|
+
name: "create_pr",
|
|
562
|
+
description: "Create a pull request for the current branch. Uses gh CLI to create the PR and updates workflow status.",
|
|
563
|
+
inputSchema: {
|
|
564
|
+
type: "object",
|
|
565
|
+
properties: {
|
|
566
|
+
workspace_path: {
|
|
567
|
+
type: "string",
|
|
568
|
+
description: "Path to the workspace directory",
|
|
569
|
+
},
|
|
570
|
+
title: {
|
|
571
|
+
type: "string",
|
|
572
|
+
description: "PR title",
|
|
573
|
+
},
|
|
574
|
+
body: {
|
|
575
|
+
type: "string",
|
|
576
|
+
description: "PR description/body",
|
|
577
|
+
},
|
|
578
|
+
},
|
|
579
|
+
required: ["workspace_path", "title"],
|
|
580
|
+
},
|
|
581
|
+
},
|
|
560
582
|
{
|
|
561
583
|
name: "get_branch_info",
|
|
562
584
|
description: "Get current git branch information including branch name, whether it's main/master, and behind/ahead counts relative to origin and main branch.",
|
|
@@ -612,6 +634,34 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
612
634
|
required: ["workspace_path"],
|
|
613
635
|
},
|
|
614
636
|
},
|
|
637
|
+
{
|
|
638
|
+
name: "get_branch_pr_status",
|
|
639
|
+
description: "Check if the current branch has an associated pull request and its status (open, merged, or closed). Useful for understanding the current state before making changes.",
|
|
640
|
+
inputSchema: {
|
|
641
|
+
type: "object",
|
|
642
|
+
properties: {
|
|
643
|
+
workspace_path: {
|
|
644
|
+
type: "string",
|
|
645
|
+
description: "Path to the workspace directory",
|
|
646
|
+
},
|
|
647
|
+
},
|
|
648
|
+
required: ["workspace_path"],
|
|
649
|
+
},
|
|
650
|
+
},
|
|
651
|
+
{
|
|
652
|
+
name: "get_workflow_recommendation",
|
|
653
|
+
description: "Get a smart recommendation for what to do before starting the workflow. Analyzes current branch, PR status, uncommitted changes, and sync status to suggest the best next action. ALWAYS call this before trigger_workflow to ensure you're following best practices.",
|
|
654
|
+
inputSchema: {
|
|
655
|
+
type: "object",
|
|
656
|
+
properties: {
|
|
657
|
+
workspace_path: {
|
|
658
|
+
type: "string",
|
|
659
|
+
description: "Path to the workspace directory",
|
|
660
|
+
},
|
|
661
|
+
},
|
|
662
|
+
required: ["workspace_path"],
|
|
663
|
+
},
|
|
664
|
+
},
|
|
615
665
|
],
|
|
616
666
|
};
|
|
617
667
|
});
|
|
@@ -1483,6 +1533,34 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1483
1533
|
return { content: [{ type: "text", text: `Error: ${err.message}` }] };
|
|
1484
1534
|
}
|
|
1485
1535
|
}
|
|
1536
|
+
case "create_pr": {
|
|
1537
|
+
const workspacePath = args?.workspace_path;
|
|
1538
|
+
const title = args?.title;
|
|
1539
|
+
const body = args?.body ?? '';
|
|
1540
|
+
if (!workspacePath) {
|
|
1541
|
+
return { content: [{ type: "text", text: "Error: workspace_path is required" }] };
|
|
1542
|
+
}
|
|
1543
|
+
if (!title) {
|
|
1544
|
+
return { content: [{ type: "text", text: "Error: title is required" }] };
|
|
1545
|
+
}
|
|
1546
|
+
try {
|
|
1547
|
+
const response = await fetch(`${CLAUDETTE_API}/api/workflow/pr`, {
|
|
1548
|
+
method: "POST",
|
|
1549
|
+
headers: { "Content-Type": "application/json" },
|
|
1550
|
+
body: JSON.stringify({ path: workspacePath, title, body }),
|
|
1551
|
+
});
|
|
1552
|
+
const result = await response.json();
|
|
1553
|
+
if (result.status === 'passed' || result.url) {
|
|
1554
|
+
return { content: [{ type: "text", text: `✅ Pull Request created!\n\nURL: ${result.url}\nPR #${result.prNumber}\n\nWorkflow advanced to code review.` }] };
|
|
1555
|
+
}
|
|
1556
|
+
else {
|
|
1557
|
+
return { content: [{ type: "text", text: `❌ Failed to create PR: ${result.error}` }] };
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
catch (err) {
|
|
1561
|
+
return { content: [{ type: "text", text: `Error: ${err.message}` }] };
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1486
1564
|
case "get_branch_info": {
|
|
1487
1565
|
const workspacePath = args?.workspace_path;
|
|
1488
1566
|
const doFetch = args?.fetch ?? false;
|
|
@@ -1582,6 +1660,103 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
1582
1660
|
return { content: [{ type: "text", text: `Error: ${err.message}` }] };
|
|
1583
1661
|
}
|
|
1584
1662
|
}
|
|
1663
|
+
case "get_branch_pr_status": {
|
|
1664
|
+
const workspacePath = args?.workspace_path;
|
|
1665
|
+
if (!workspacePath) {
|
|
1666
|
+
return { content: [{ type: "text", text: "Error: workspace_path is required" }] };
|
|
1667
|
+
}
|
|
1668
|
+
try {
|
|
1669
|
+
const response = await fetch(`${CLAUDETTE_API}/api/workflow/pr-status?path=${encodeURIComponent(workspacePath)}`);
|
|
1670
|
+
const status = await response.json();
|
|
1671
|
+
let output = `Branch PR Status\n${'='.repeat(50)}\n\n`;
|
|
1672
|
+
if (!status.hasPR) {
|
|
1673
|
+
output += `No pull request found for this branch.\n`;
|
|
1674
|
+
output += `\nThis is normal if:\n`;
|
|
1675
|
+
output += ` • You're on main/master\n`;
|
|
1676
|
+
output += ` • This is a new feature branch without a PR yet\n`;
|
|
1677
|
+
}
|
|
1678
|
+
else {
|
|
1679
|
+
const statusIcon = status.prStatus === 'open' ? '🟢' :
|
|
1680
|
+
status.prStatus === 'merged' ? '🟣' : '🔴';
|
|
1681
|
+
output += `${statusIcon} PR #${status.prNumber}: ${status.prStatus.toUpperCase()}\n`;
|
|
1682
|
+
output += `Title: ${status.prTitle}\n`;
|
|
1683
|
+
output += `URL: ${status.prUrl}\n`;
|
|
1684
|
+
if (status.isDraft) {
|
|
1685
|
+
output += `📝 This is a draft PR\n`;
|
|
1686
|
+
}
|
|
1687
|
+
output += `\n`;
|
|
1688
|
+
if (status.prStatus === 'open') {
|
|
1689
|
+
output += `ℹ️ New commits will be added to this existing PR.\n`;
|
|
1690
|
+
}
|
|
1691
|
+
else if (status.prStatus === 'merged') {
|
|
1692
|
+
output += `⚠️ This PR was merged. Consider switching to main and creating a new branch.\n`;
|
|
1693
|
+
}
|
|
1694
|
+
else {
|
|
1695
|
+
output += `⚠️ This PR was closed without merging. You may want to create a new branch or reopen it.\n`;
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
return { content: [{ type: "text", text: output }] };
|
|
1699
|
+
}
|
|
1700
|
+
catch (err) {
|
|
1701
|
+
return { content: [{ type: "text", text: `Error: ${err.message}` }] };
|
|
1702
|
+
}
|
|
1703
|
+
}
|
|
1704
|
+
case "get_workflow_recommendation": {
|
|
1705
|
+
const workspacePath = args?.workspace_path;
|
|
1706
|
+
if (!workspacePath) {
|
|
1707
|
+
return { content: [{ type: "text", text: "Error: workspace_path is required" }] };
|
|
1708
|
+
}
|
|
1709
|
+
try {
|
|
1710
|
+
const response = await fetch(`${CLAUDETTE_API}/api/workflow/recommendation?path=${encodeURIComponent(workspacePath)}`);
|
|
1711
|
+
const rec = await response.json();
|
|
1712
|
+
let output = `Workflow Recommendation\n${'='.repeat(50)}\n\n`;
|
|
1713
|
+
// Action header with icon
|
|
1714
|
+
const actionIcons = {
|
|
1715
|
+
'start_workflow': '▶️',
|
|
1716
|
+
'create_feature_branch': '🌿',
|
|
1717
|
+
'add_to_existing_pr': '📝',
|
|
1718
|
+
'switch_to_main': '🔄',
|
|
1719
|
+
'create_new_branch': '🆕',
|
|
1720
|
+
'sync_branch_first': '🔀',
|
|
1721
|
+
'no_changes': '📭',
|
|
1722
|
+
};
|
|
1723
|
+
const icon = actionIcons[rec.action] || '❓';
|
|
1724
|
+
output += `${icon} RECOMMENDED ACTION: ${rec.action.replace(/_/g, ' ').toUpperCase()}\n\n`;
|
|
1725
|
+
// Current state summary
|
|
1726
|
+
output += `Current State:\n`;
|
|
1727
|
+
output += `────────────────────────────────────────\n`;
|
|
1728
|
+
output += ` Branch: ${rec.details.currentBranch}${rec.details.isMain ? ' (main)' : ''}\n`;
|
|
1729
|
+
output += ` Changes: ${rec.details.changeCount} uncommitted file(s)\n`;
|
|
1730
|
+
if (rec.details.prStatus) {
|
|
1731
|
+
output += ` PR: #${rec.details.prStatus.prNumber} (${rec.details.prStatus.prStatus})\n`;
|
|
1732
|
+
}
|
|
1733
|
+
if (rec.details.behindMain && rec.details.behindMain > 0) {
|
|
1734
|
+
output += ` ⚠️ Behind main: ${rec.details.behindMain} commit(s)\n`;
|
|
1735
|
+
}
|
|
1736
|
+
output += `\n`;
|
|
1737
|
+
// Reason and suggestion
|
|
1738
|
+
output += `Why:\n`;
|
|
1739
|
+
output += `────────────────────────────────────────\n`;
|
|
1740
|
+
output += `${rec.reason}\n\n`;
|
|
1741
|
+
output += `Suggestion:\n`;
|
|
1742
|
+
output += `────────────────────────────────────────\n`;
|
|
1743
|
+
output += `${rec.suggestion}\n\n`;
|
|
1744
|
+
// What will happen
|
|
1745
|
+
if (rec.consequences.length > 0) {
|
|
1746
|
+
output += `What will happen:\n`;
|
|
1747
|
+
output += `────────────────────────────────────────\n`;
|
|
1748
|
+
for (const c of rec.consequences) {
|
|
1749
|
+
output += ` • ${c}\n`;
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
output += `\n${'='.repeat(50)}\n`;
|
|
1753
|
+
output += `Trust this recommendation and proceed accordingly.\n`;
|
|
1754
|
+
return { content: [{ type: "text", text: output }] };
|
|
1755
|
+
}
|
|
1756
|
+
catch (err) {
|
|
1757
|
+
return { content: [{ type: "text", text: `Error: ${err.message}` }] };
|
|
1758
|
+
}
|
|
1759
|
+
}
|
|
1585
1760
|
default:
|
|
1586
1761
|
return { content: [{ type: "text", text: `Unknown tool: ${name}` }] };
|
|
1587
1762
|
}
|
package/package.json
CHANGED