@andre.buzeli/git-mcp 16.1.4 → 16.1.6
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 +3 -2
- package/package.json +1 -1
- package/src/index.js +38 -47
- package/src/tools/git-branches.js +5 -2
- package/src/tools/git-clone.js +5 -2
- package/src/tools/git-config.js +5 -2
- package/src/tools/git-diff.js +5 -2
- package/src/tools/git-files.js +5 -2
- package/src/tools/git-history.js +5 -2
- package/src/tools/git-ignore.js +5 -2
- package/src/tools/git-issues.js +5 -2
- package/src/tools/git-merge.js +5 -2
- package/src/tools/git-pulls.js +5 -2
- package/src/tools/git-remote.js +5 -2
- package/src/tools/git-reset.js +5 -2
- package/src/tools/git-stash.js +5 -2
- package/src/tools/git-sync.js +5 -2
- package/src/tools/git-tags.js +5 -2
- package/src/tools/git-workflow.js +6 -2
- package/src/tools/git-worktree.js +5 -2
- package/src/utils/errors.js +21 -0
package/README.md
CHANGED
|
@@ -17,10 +17,11 @@ Servidor MCP (Model Context Protocol) para operações Git locais sem git instal
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
-
}
|
|
20
|
+
}
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
## Tools
|
|
23
|
+
## Tools
|
|
24
|
+
|
|
24
25
|
|
|
25
26
|
- git-workflow: init, status, add, remove, commit, ensure-remotes, push
|
|
26
27
|
- git-update: status -> add -> commit -> push (all-in-one)
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -59,53 +59,44 @@ const server = new Server(
|
|
|
59
59
|
},
|
|
60
60
|
instructions: `# git-mcp — Instruções para AI Agents
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
| Ajuda sobre tools | git-help | - | query/listTools/showFlows |
|
|
101
|
-
|
|
102
|
-
## Exemplo Completo (ação mais comum)
|
|
103
|
-
\`\`\`json
|
|
104
|
-
{ "projectPath": "/caminho/do/projeto", "action": "update", "message": "feat: descrição das mudanças" }
|
|
105
|
-
\`\`\`
|
|
106
|
-
|
|
107
|
-
## Dica
|
|
108
|
-
Use git-help action="listTools" para ver todas as tools e actions disponíveis em tempo real.`
|
|
62
|
+
ATENÇÃO: NUNCA chame uma tool sem os parâmetros obrigatórios. Toda call incompleta retorna erro.
|
|
63
|
+
|
|
64
|
+
## Parâmetros obrigatórios em TODAS as tools (exceto git-help)
|
|
65
|
+
- "projectPath": caminho absoluto do projeto no sistema de arquivos do usuário. O servidor NÃO detecta automaticamente.
|
|
66
|
+
- "action": string com o nome da action a executar (ver enum no schema de cada tool)
|
|
67
|
+
|
|
68
|
+
## Exemplos prontos para uso — copie e substitua os valores
|
|
69
|
+
|
|
70
|
+
git-workflow (update): {"projectPath":"<PATH>","action":"update","message":"feat: descrição"}
|
|
71
|
+
git-workflow (status): {"projectPath":"<PATH>","action":"status"}
|
|
72
|
+
git-workflow (init): {"projectPath":"<PATH>","action":"init"}
|
|
73
|
+
git-workflow (push): {"projectPath":"<PATH>","action":"push"}
|
|
74
|
+
git-diff (show): {"projectPath":"<PATH>","action":"show"}
|
|
75
|
+
git-diff (compare): {"projectPath":"<PATH>","action":"compare","target":"main"}
|
|
76
|
+
git-branches (list): {"projectPath":"<PATH>","action":"list"}
|
|
77
|
+
git-branches (create): {"projectPath":"<PATH>","action":"create","branch":"feature/x"}
|
|
78
|
+
git-branches (checkout):{"projectPath":"<PATH>","action":"checkout","branch":"main"}
|
|
79
|
+
git-merge (merge): {"projectPath":"<PATH>","action":"merge","branch":"feature/x"}
|
|
80
|
+
git-tags (create): {"projectPath":"<PATH>","action":"create","tag":"v1.0.0"}
|
|
81
|
+
git-tags (push): {"projectPath":"<PATH>","action":"push","tag":"v1.0.0"}
|
|
82
|
+
git-stash (save): {"projectPath":"<PATH>","action":"save"}
|
|
83
|
+
git-stash (pop): {"projectPath":"<PATH>","action":"pop"}
|
|
84
|
+
git-reset (soft): {"projectPath":"<PATH>","action":"soft","ref":"HEAD~1"}
|
|
85
|
+
git-reset (hard): {"projectPath":"<PATH>","action":"hard","ref":"HEAD~1"}
|
|
86
|
+
git-history (log): {"projectPath":"<PATH>","action":"log"}
|
|
87
|
+
git-remote (ensure): {"projectPath":"<PATH>","action":"ensure"}
|
|
88
|
+
git-remote (list): {"projectPath":"<PATH>","action":"list"}
|
|
89
|
+
git-remote (release-create): {"projectPath":"<PATH>","action":"release-create","tag":"v1.0.0","name":"Release v1.0.0"}
|
|
90
|
+
git-worktree (list): {"projectPath":"<PATH>","action":"list"}
|
|
91
|
+
git-worktree (add): {"projectPath":"<PATH>","action":"add","branch":"feature/x"}
|
|
92
|
+
git-sync (pull): {"projectPath":"<PATH>","action":"pull"}
|
|
93
|
+
git-config (get): {"projectPath":"<PATH>","action":"get","key":"user.name"}
|
|
94
|
+
git-ignore (add): {"projectPath":"<PATH>","action":"add","patterns":["node_modules/"]}
|
|
95
|
+
git-files (read): {"projectPath":"<PATH>","action":"read","filepath":"package.json"}
|
|
96
|
+
git-issues (create): {"projectPath":"<PATH>","action":"create","title":"Bug: descrição"}
|
|
97
|
+
git-pulls (create): {"projectPath":"<PATH>","action":"create","head":"feature/x","base":"main","title":"feat: x"}
|
|
98
|
+
git-clone (clone): {"projectPath":"<PARENT_DIR>","action":"clone","url":"https://github.com/user/repo.git"}
|
|
99
|
+
git-help: {"listTools":true} ← única tool sem projectPath/action obrigatórios`
|
|
109
100
|
}
|
|
110
101
|
);
|
|
111
102
|
server.connect(transport);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Ajv from "ajv";
|
|
2
|
-
import { asToolError, asToolResult, errorToResponse } from "../utils/errors.js";
|
|
2
|
+
import { asToolError, asToolResult, errorToResponse, handleEmptyCall } from "../utils/errors.js";
|
|
3
3
|
import { validateProjectPath } from "../utils/repoHelpers.js";
|
|
4
4
|
|
|
5
5
|
const ajv = new Ajv({ allErrors: true });
|
|
@@ -59,8 +59,11 @@ CONVENÇÕES DE NOMES:
|
|
|
59
59
|
- release/versao: Para releases`;
|
|
60
60
|
|
|
61
61
|
async function handle(args) {
|
|
62
|
+
const emptyHelp = handleEmptyCall(args, inputSchema, "git-branches", { projectPath: "/path/to/project", action: "list" });
|
|
63
|
+
if (emptyHelp) return emptyHelp;
|
|
64
|
+
|
|
62
65
|
const validate = ajv.compile(inputSchema);
|
|
63
|
-
if (!validate(args
|
|
66
|
+
if (!validate(args)) return asToolError("VALIDATION_ERROR", "Parâmetros inválidos", validate.errors);
|
|
64
67
|
const { projectPath, action } = args;
|
|
65
68
|
try {
|
|
66
69
|
validateProjectPath(projectPath);
|
package/src/tools/git-clone.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Ajv from "ajv";
|
|
2
|
-
import { asToolError, asToolResult, errorToResponse } from "../utils/errors.js";
|
|
2
|
+
import { asToolError, asToolResult, errorToResponse, handleEmptyCall } from "../utils/errors.js";
|
|
3
3
|
import { validateProjectPath } from "../utils/repoHelpers.js";
|
|
4
4
|
import { withRetry } from "../utils/retry.js";
|
|
5
5
|
|
|
@@ -55,8 +55,11 @@ EXEMPLO:
|
|
|
55
55
|
- Shallow clone (rápido): action='clone' url='...' depth=1`;
|
|
56
56
|
|
|
57
57
|
async function handle(args) {
|
|
58
|
+
const emptyHelp = handleEmptyCall(args, inputSchema, "git-clone", { projectPath: "/path/to/parent", action: "clone", url: "https://github.com/user/repo.git" });
|
|
59
|
+
if (emptyHelp) return emptyHelp;
|
|
60
|
+
|
|
58
61
|
const validate = ajv.compile(inputSchema);
|
|
59
|
-
if (!validate(args
|
|
62
|
+
if (!validate(args)) return asToolError("VALIDATION_ERROR", "Parâmetros inválidos", validate.errors);
|
|
60
63
|
|
|
61
64
|
// projectPath aqui é o diretório PAI
|
|
62
65
|
const { projectPath, action, url } = args;
|
package/src/tools/git-config.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Ajv from "ajv";
|
|
2
|
-
import { asToolError, asToolResult, errorToResponse } from "../utils/errors.js";
|
|
2
|
+
import { asToolError, asToolResult, errorToResponse, handleEmptyCall } from "../utils/errors.js";
|
|
3
3
|
import { validateProjectPath } from "../utils/repoHelpers.js";
|
|
4
4
|
import { withRetry } from "../utils/retry.js";
|
|
5
5
|
|
|
@@ -63,8 +63,11 @@ EXEMPLOS:
|
|
|
63
63
|
- Ver nome: action='get' key='user.name'`;
|
|
64
64
|
|
|
65
65
|
async function handle(args) {
|
|
66
|
+
const emptyHelp = handleEmptyCall(args, inputSchema, "git-config", { projectPath: "/path/to/project", action: "get", key: "user.name" });
|
|
67
|
+
if (emptyHelp) return emptyHelp;
|
|
68
|
+
|
|
66
69
|
const validate = ajv.compile(inputSchema);
|
|
67
|
-
if (!validate(args
|
|
70
|
+
if (!validate(args)) return asToolError("VALIDATION_ERROR", "Parâmetros inválidos", validate.errors);
|
|
68
71
|
const { projectPath, action } = args;
|
|
69
72
|
const scope = args.scope || "local";
|
|
70
73
|
try {
|
package/src/tools/git-diff.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Ajv from "ajv";
|
|
2
|
-
import { asToolError, asToolResult, errorToResponse } from "../utils/errors.js";
|
|
2
|
+
import { asToolError, asToolResult, errorToResponse, handleEmptyCall } from "../utils/errors.js";
|
|
3
3
|
import { validateProjectPath } from "../utils/repoHelpers.js";
|
|
4
4
|
|
|
5
5
|
const ajv = new Ajv({ allErrors: true });
|
|
@@ -70,8 +70,11 @@ EXEMPLOS:
|
|
|
70
70
|
- Estatísticas de mudança: action='stat' target='HEAD~1'`;
|
|
71
71
|
|
|
72
72
|
async function handle(args) {
|
|
73
|
+
const emptyHelp = handleEmptyCall(args, inputSchema, "git-diff", { projectPath: "/path/to/project", action: "show" });
|
|
74
|
+
if (emptyHelp) return emptyHelp;
|
|
75
|
+
|
|
73
76
|
const validate = ajv.compile(inputSchema);
|
|
74
|
-
if (!validate(args
|
|
77
|
+
if (!validate(args)) return asToolError("VALIDATION_ERROR", "Parâmetros inválidos", validate.errors);
|
|
75
78
|
const { projectPath, action } = args;
|
|
76
79
|
|
|
77
80
|
try {
|
package/src/tools/git-files.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Ajv from "ajv";
|
|
2
|
-
import { asToolError, asToolResult, errorToResponse } from "../utils/errors.js";
|
|
2
|
+
import { asToolError, asToolResult, errorToResponse, handleEmptyCall } from "../utils/errors.js";
|
|
3
3
|
import { validateProjectPath, withRetry } from "../utils/repoHelpers.js";
|
|
4
4
|
|
|
5
5
|
const ajv = new Ajv({ allErrors: true });
|
|
@@ -52,8 +52,11 @@ EXEMPLOS:
|
|
|
52
52
|
NOTA: Esta tool lê arquivos do histórico Git, não do sistema de arquivos.`;
|
|
53
53
|
|
|
54
54
|
async function handle(args) {
|
|
55
|
+
const emptyHelp = handleEmptyCall(args, inputSchema, "git-files", { projectPath: "/path/to/project", action: "list" });
|
|
56
|
+
if (emptyHelp) return emptyHelp;
|
|
57
|
+
|
|
55
58
|
const validate = ajv.compile(inputSchema);
|
|
56
|
-
if (!validate(args
|
|
59
|
+
if (!validate(args)) return asToolError("VALIDATION_ERROR", "Parâmetros inválidos", validate.errors);
|
|
57
60
|
const { projectPath, action } = args;
|
|
58
61
|
try {
|
|
59
62
|
validateProjectPath(projectPath);
|
package/src/tools/git-history.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Ajv from "ajv";
|
|
2
|
-
import { asToolError, asToolResult, errorToResponse } from "../utils/errors.js";
|
|
2
|
+
import { asToolError, asToolResult, errorToResponse, handleEmptyCall } from "../utils/errors.js";
|
|
3
3
|
import { validateProjectPath, withRetry } from "../utils/repoHelpers.js";
|
|
4
4
|
|
|
5
5
|
const ajv = new Ajv({ allErrors: true });
|
|
@@ -58,8 +58,11 @@ EXEMPLOS:
|
|
|
58
58
|
- Ver histórico de tag: action='log' ref='v1.0.0'`;
|
|
59
59
|
|
|
60
60
|
async function handle(args) {
|
|
61
|
+
const emptyHelp = handleEmptyCall(args, inputSchema, "git-history", { projectPath: "/path/to/project", action: "log" });
|
|
62
|
+
if (emptyHelp) return emptyHelp;
|
|
63
|
+
|
|
61
64
|
const validate = ajv.compile(inputSchema);
|
|
62
|
-
if (!validate(args
|
|
65
|
+
if (!validate(args)) return asToolError("VALIDATION_ERROR", "Parâmetros inválidos", validate.errors);
|
|
63
66
|
const { projectPath, action } = args;
|
|
64
67
|
try {
|
|
65
68
|
validateProjectPath(projectPath);
|
package/src/tools/git-ignore.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Ajv from "ajv";
|
|
2
|
-
import { asToolError, asToolResult, errorToResponse } from "../utils/errors.js";
|
|
2
|
+
import { asToolError, asToolResult, errorToResponse, handleEmptyCall } from "../utils/errors.js";
|
|
3
3
|
import { validateProjectPath } from "../utils/repoHelpers.js";
|
|
4
4
|
import { withRetry } from "../utils/retry.js";
|
|
5
5
|
|
|
@@ -59,8 +59,11 @@ EXEMPLOS:
|
|
|
59
59
|
- Adicionar padrão: action='add' patterns=['*.tmp']`;
|
|
60
60
|
|
|
61
61
|
async function handle(args) {
|
|
62
|
+
const emptyHelp = handleEmptyCall(args, inputSchema, "git-ignore", { projectPath: "/path/to/project", action: "list" });
|
|
63
|
+
if (emptyHelp) return emptyHelp;
|
|
64
|
+
|
|
62
65
|
const validate = ajv.compile(inputSchema);
|
|
63
|
-
if (!validate(args
|
|
66
|
+
if (!validate(args)) return asToolError("VALIDATION_ERROR", "Parâmetros inválidos", validate.errors);
|
|
64
67
|
const { projectPath, action } = args;
|
|
65
68
|
const patterns = Array.isArray(args.patterns) ? args.patterns : [];
|
|
66
69
|
try {
|
package/src/tools/git-issues.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Ajv from "ajv";
|
|
2
2
|
import axios from "axios";
|
|
3
|
-
import { asToolError, asToolResult, errorToResponse } from "../utils/errors.js";
|
|
3
|
+
import { asToolError, asToolResult, errorToResponse, handleEmptyCall } from "../utils/errors.js";
|
|
4
4
|
import { getRepoNameFromPath, validateProjectPath, withRetry } from "../utils/repoHelpers.js";
|
|
5
5
|
import { runBoth } from "../utils/providerExec.js";
|
|
6
6
|
|
|
@@ -66,8 +66,11 @@ BOAS PRÁTICAS:
|
|
|
66
66
|
- Use labels para categorizar (via git-remote label-create)`;
|
|
67
67
|
|
|
68
68
|
async function handle(args) {
|
|
69
|
+
const emptyHelp = handleEmptyCall(args, inputSchema, "git-issues", { projectPath: "/path/to/project", action: "list" });
|
|
70
|
+
if (emptyHelp) return emptyHelp;
|
|
71
|
+
|
|
69
72
|
const validate = ajv.compile(inputSchema);
|
|
70
|
-
if (!validate(args
|
|
73
|
+
if (!validate(args)) return asToolError("VALIDATION_ERROR", "Parâmetros inválidos", validate.errors);
|
|
71
74
|
validateProjectPath(args.projectPath);
|
|
72
75
|
const repo = getRepoNameFromPath(args.projectPath);
|
|
73
76
|
try {
|
package/src/tools/git-merge.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Ajv from "ajv";
|
|
2
|
-
import { asToolError, asToolResult, errorToResponse, createError } from "../utils/errors.js";
|
|
2
|
+
import { asToolError, asToolResult, errorToResponse, createError, handleEmptyCall } from "../utils/errors.js";
|
|
3
3
|
import { validateProjectPath } from "../utils/repoHelpers.js";
|
|
4
4
|
|
|
5
5
|
const ajv = new Ajv({ allErrors: true });
|
|
@@ -68,8 +68,11 @@ SQUASH:
|
|
|
68
68
|
- Útil para manter histórico limpo`;
|
|
69
69
|
|
|
70
70
|
async function handle(args) {
|
|
71
|
+
const emptyHelp = handleEmptyCall(args, inputSchema, "git-merge", { projectPath: "/path/to/project", action: "status" });
|
|
72
|
+
if (emptyHelp) return emptyHelp;
|
|
73
|
+
|
|
71
74
|
const validate = ajv.compile(inputSchema);
|
|
72
|
-
if (!validate(args
|
|
75
|
+
if (!validate(args)) return asToolError("VALIDATION_ERROR", "Parâmetros inválidos", validate.errors);
|
|
73
76
|
const { projectPath, action } = args;
|
|
74
77
|
|
|
75
78
|
try {
|
package/src/tools/git-pulls.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Ajv from "ajv";
|
|
2
2
|
import axios from "axios";
|
|
3
|
-
import { asToolError, asToolResult, errorToResponse } from "../utils/errors.js";
|
|
3
|
+
import { asToolError, asToolResult, errorToResponse, handleEmptyCall } from "../utils/errors.js";
|
|
4
4
|
import { getRepoNameFromPath, validateProjectPath, withRetry } from "../utils/repoHelpers.js";
|
|
5
5
|
import { runBoth } from "../utils/providerExec.js";
|
|
6
6
|
|
|
@@ -76,8 +76,11 @@ AÇÕES:
|
|
|
76
76
|
NOTA: O PR é criado em AMBOS os providers simultaneamente.`;
|
|
77
77
|
|
|
78
78
|
async function handle(args) {
|
|
79
|
+
const emptyHelp = handleEmptyCall(args, inputSchema, "git-pulls", { projectPath: "/path/to/project", action: "list" });
|
|
80
|
+
if (emptyHelp) return emptyHelp;
|
|
81
|
+
|
|
79
82
|
const validate = ajv.compile(inputSchema);
|
|
80
|
-
if (!validate(args
|
|
83
|
+
if (!validate(args)) return asToolError("VALIDATION_ERROR", "Parâmetros inválidos", validate.errors);
|
|
81
84
|
validateProjectPath(args.projectPath);
|
|
82
85
|
const repo = getRepoNameFromPath(args.projectPath);
|
|
83
86
|
try {
|
package/src/tools/git-remote.js
CHANGED
|
@@ -3,7 +3,7 @@ import axios from "axios";
|
|
|
3
3
|
import fs from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import archiver from "archiver";
|
|
6
|
-
import { asToolError, asToolResult, errorToResponse, mapExternalError } from "../utils/errors.js";
|
|
6
|
+
import { asToolError, asToolResult, errorToResponse, mapExternalError, handleEmptyCall } from "../utils/errors.js";
|
|
7
7
|
import { getRepoNameFromPath, validateProjectPath, withRetry } from "../utils/repoHelpers.js";
|
|
8
8
|
import { runBoth } from "../utils/providerExec.js";
|
|
9
9
|
import { sendLog, requestConfirmation } from "../utils/mcpNotify.js";
|
|
@@ -218,8 +218,11 @@ QUANDO USAR:
|
|
|
218
218
|
- Para configurar tópicos: use action='topics-set'`;
|
|
219
219
|
|
|
220
220
|
async function handle(args) {
|
|
221
|
+
const emptyHelp = handleEmptyCall(args, inputSchema, "git-remote", { projectPath: "/path/to/project", action: "list" });
|
|
222
|
+
if (emptyHelp) return emptyHelp;
|
|
223
|
+
|
|
221
224
|
const validate = ajv.compile(inputSchema);
|
|
222
|
-
if (!validate(args
|
|
225
|
+
if (!validate(args)) return asToolError("VALIDATION_ERROR", "Parâmetros inválidos", validate.errors);
|
|
223
226
|
const { projectPath, action } = args;
|
|
224
227
|
try {
|
|
225
228
|
validateProjectPath(projectPath);
|
package/src/tools/git-reset.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Ajv from "ajv";
|
|
2
|
-
import { asToolError, asToolResult, errorToResponse } from "../utils/errors.js";
|
|
2
|
+
import { asToolError, asToolResult, errorToResponse, handleEmptyCall } from "../utils/errors.js";
|
|
3
3
|
import { validateProjectPath, withRetry } from "../utils/repoHelpers.js";
|
|
4
4
|
import { sendLog, requestConfirmation } from "../utils/mcpNotify.js";
|
|
5
5
|
|
|
@@ -57,8 +57,11 @@ REFERÊNCIAS:
|
|
|
57
57
|
- abc1234: SHA específico do commit`;
|
|
58
58
|
|
|
59
59
|
async function handle(args) {
|
|
60
|
+
const emptyHelp = handleEmptyCall(args, inputSchema, "git-reset", { projectPath: "/path/to/project", action: "soft", ref: "HEAD~1" });
|
|
61
|
+
if (emptyHelp) return emptyHelp;
|
|
62
|
+
|
|
60
63
|
const validate = ajv.compile(inputSchema);
|
|
61
|
-
if (!validate(args
|
|
64
|
+
if (!validate(args)) return asToolError("VALIDATION_ERROR", "Parâmetros inválidos", validate.errors);
|
|
62
65
|
const { projectPath, action, ref } = args;
|
|
63
66
|
try {
|
|
64
67
|
validateProjectPath(projectPath);
|
package/src/tools/git-stash.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Ajv from "ajv";
|
|
2
|
-
import { asToolError, asToolResult, errorToResponse } from "../utils/errors.js";
|
|
2
|
+
import { asToolError, asToolResult, errorToResponse, handleEmptyCall } from "../utils/errors.js";
|
|
3
3
|
import { validateProjectPath } from "../utils/repoHelpers.js";
|
|
4
4
|
import { withRetry } from "../utils/retry.js";
|
|
5
5
|
|
|
@@ -67,8 +67,11 @@ AÇÕES:
|
|
|
67
67
|
- clear: Remover todos os stashes`;
|
|
68
68
|
|
|
69
69
|
async function handle(args) {
|
|
70
|
+
const emptyHelp = handleEmptyCall(args, inputSchema, "git-stash", { projectPath: "/path/to/project", action: "list" });
|
|
71
|
+
if (emptyHelp) return emptyHelp;
|
|
72
|
+
|
|
70
73
|
const validate = ajv.compile(inputSchema);
|
|
71
|
-
if (!validate(args
|
|
74
|
+
if (!validate(args)) return asToolError("VALIDATION_ERROR", "Parâmetros inválidos", validate.errors);
|
|
72
75
|
const { projectPath, action } = args;
|
|
73
76
|
try {
|
|
74
77
|
validateProjectPath(projectPath);
|
package/src/tools/git-sync.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Ajv from "ajv";
|
|
2
|
-
import { asToolError, asToolResult, errorToResponse } from "../utils/errors.js";
|
|
2
|
+
import { asToolError, asToolResult, errorToResponse, handleEmptyCall } from "../utils/errors.js";
|
|
3
3
|
import { validateProjectPath, withRetry } from "../utils/repoHelpers.js";
|
|
4
4
|
|
|
5
5
|
const ajv = new Ajv({ allErrors: true });
|
|
@@ -54,8 +54,11 @@ FLUXO RECOMENDADO:
|
|
|
54
54
|
NOTA: Se pull falhar com conflito, resolva manualmente e faça commit.`;
|
|
55
55
|
|
|
56
56
|
async function handle(args) {
|
|
57
|
+
const emptyHelp = handleEmptyCall(args, inputSchema, "git-sync", { projectPath: "/path/to/project", action: "fetch" });
|
|
58
|
+
if (emptyHelp) return emptyHelp;
|
|
59
|
+
|
|
57
60
|
const validate = ajv.compile(inputSchema);
|
|
58
|
-
if (!validate(args
|
|
61
|
+
if (!validate(args)) return asToolError("VALIDATION_ERROR", "Parâmetros inválidos", validate.errors);
|
|
59
62
|
const { projectPath, action } = args;
|
|
60
63
|
try {
|
|
61
64
|
validateProjectPath(projectPath);
|
package/src/tools/git-tags.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Ajv from "ajv";
|
|
2
|
-
import { asToolError, asToolResult, errorToResponse } from "../utils/errors.js";
|
|
2
|
+
import { asToolError, asToolResult, errorToResponse, handleEmptyCall } from "../utils/errors.js";
|
|
3
3
|
import { validateProjectPath, withRetry } from "../utils/repoHelpers.js";
|
|
4
4
|
|
|
5
5
|
const ajv = new Ajv({ allErrors: true });
|
|
@@ -61,8 +61,11 @@ FLUXO TÍPICO:
|
|
|
61
61
|
2. git-tags push tag='v1.0.0'`;
|
|
62
62
|
|
|
63
63
|
async function handle(args) {
|
|
64
|
+
const emptyHelp = handleEmptyCall(args, inputSchema, "git-tags", { projectPath: "/path/to/project", action: "list" });
|
|
65
|
+
if (emptyHelp) return emptyHelp;
|
|
66
|
+
|
|
64
67
|
const validate = ajv.compile(inputSchema);
|
|
65
|
-
if (!validate(args
|
|
68
|
+
if (!validate(args)) return asToolError("VALIDATION_ERROR", "Parâmetros inválidos", validate.errors);
|
|
66
69
|
const { projectPath, action } = args;
|
|
67
70
|
try {
|
|
68
71
|
validateProjectPath(projectPath);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Ajv from "ajv";
|
|
2
2
|
import fs from "fs";
|
|
3
3
|
import path from "path";
|
|
4
|
-
import { asToolError, asToolResult, errorToResponse, createError } from "../utils/errors.js";
|
|
4
|
+
import { asToolError, asToolResult, errorToResponse, createError, handleEmptyCall } from "../utils/errors.js";
|
|
5
5
|
import { getRepoNameFromPath, detectProjectType, GITIGNORE_TEMPLATES, validateProjectPath, withRetry } from "../utils/repoHelpers.js";
|
|
6
6
|
import { resolveWorktreeContext, isProtectedPath } from "../utils/worktreeResolver.js";
|
|
7
7
|
import { sendLog } from "../utils/mcpNotify.js";
|
|
@@ -134,8 +134,12 @@ EXEMPLOS DE USO:
|
|
|
134
134
|
• Ver mudanças: { "projectPath": "/path/to/project", "action": "status" }`;
|
|
135
135
|
|
|
136
136
|
async function handle(args) {
|
|
137
|
+
// Call vazia = modelo tentando descobrir o schema. Retorna help em vez de erro.
|
|
138
|
+
const emptyHelp = handleEmptyCall(args, inputSchema, "git-workflow", { projectPath: "/path/to/project", action: "update", message: "feat: descrição" });
|
|
139
|
+
if (emptyHelp) return emptyHelp;
|
|
140
|
+
|
|
137
141
|
const validate = ajv.compile(inputSchema);
|
|
138
|
-
if (!validate(args
|
|
142
|
+
if (!validate(args)) {
|
|
139
143
|
return asToolError("VALIDATION_ERROR", "Parâmetros inválidos", validate.errors);
|
|
140
144
|
}
|
|
141
145
|
const { projectPath, action } = args;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Ajv from "ajv";
|
|
2
2
|
import fs from "fs";
|
|
3
3
|
import path from "path";
|
|
4
|
-
import { asToolError, asToolResult, errorToResponse } from "../utils/errors.js";
|
|
4
|
+
import { asToolError, asToolResult, errorToResponse, handleEmptyCall } from "../utils/errors.js";
|
|
5
5
|
import { validateProjectPath, withRetry } from "../utils/repoHelpers.js";
|
|
6
6
|
import { resolveWorktreeContext, isProtectedPath } from "../utils/worktreeResolver.js";
|
|
7
7
|
|
|
@@ -73,8 +73,11 @@ AÇÕES:
|
|
|
73
73
|
- set-channel: Configurar canal de deploy (prod/beta/alpha)`;
|
|
74
74
|
|
|
75
75
|
async function handle(args) {
|
|
76
|
+
const emptyHelp = handleEmptyCall(args, inputSchema, "git-worktree", { projectPath: "/path/to/project", action: "list" });
|
|
77
|
+
if (emptyHelp) return emptyHelp;
|
|
78
|
+
|
|
76
79
|
const validate = ajv.compile(inputSchema);
|
|
77
|
-
if (!validate(args
|
|
80
|
+
if (!validate(args)) return asToolError("VALIDATION_ERROR", "Parâmetros inválidos", validate.errors);
|
|
78
81
|
const { projectPath, action } = args;
|
|
79
82
|
let effectivePath = projectPath;
|
|
80
83
|
let worktreeCtx = null;
|
package/src/utils/errors.js
CHANGED
|
@@ -432,3 +432,24 @@ export function errorToResponse(error) {
|
|
|
432
432
|
const mapped = mapExternalError(error);
|
|
433
433
|
return asToolError(mapped.code, mapped.message, mapped.data);
|
|
434
434
|
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Detecta call vazia (sem projectPath/action) e retorna help em vez de erro seco.
|
|
438
|
+
* Isso evita que modelos façam "tool probing" — uma call vazia para descobrir o schema.
|
|
439
|
+
* @param {object} args - Argumentos recebidos
|
|
440
|
+
* @param {object} inputSchema - Schema da tool
|
|
441
|
+
* @param {string} toolName - Nome da tool
|
|
442
|
+
* @param {object} example - Exemplo de uso mínimo
|
|
443
|
+
* @returns {object|null} - Resposta de help, ou null se args não estão vazios
|
|
444
|
+
*/
|
|
445
|
+
export function handleEmptyCall(args, inputSchema, toolName, example) {
|
|
446
|
+
if (args && Object.keys(args).length > 0) return null;
|
|
447
|
+
return asToolResult({
|
|
448
|
+
help: true,
|
|
449
|
+
tool: toolName,
|
|
450
|
+
requiredParams: (inputSchema.required || []).join(", "),
|
|
451
|
+
example,
|
|
452
|
+
actions: inputSchema.properties?.action?.enum || [],
|
|
453
|
+
hint: `Sempre inclua ${(inputSchema.required || []).join(" e ")} na chamada.`
|
|
454
|
+
});
|
|
455
|
+
}
|