jazz-ai 0.2.2 → 0.4.3
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 +8 -6
- package/dist/cli/commands/chat-agent.d.ts +3 -1
- package/dist/cli/commands/chat-agent.d.ts.map +1 -1
- package/dist/cli/commands/chat-agent.js +180 -102
- package/dist/cli/commands/chat-agent.js.map +1 -1
- package/dist/cli/commands/edit-agent.d.ts +2 -2
- package/dist/cli/commands/edit-agent.d.ts.map +1 -1
- package/dist/cli/commands/edit-agent.js +20 -10
- package/dist/cli/commands/edit-agent.js.map +1 -1
- package/dist/cli/commands/task-agent.d.ts +1 -1
- package/dist/cli/commands/task-agent.d.ts.map +1 -1
- package/dist/cli/commands/task-agent.js +6 -6
- package/dist/cli/commands/task-agent.js.map +1 -1
- package/dist/constants/agent.d.ts +2 -0
- package/dist/constants/agent.d.ts.map +1 -0
- package/dist/constants/agent.js +5 -0
- package/dist/constants/agent.js.map +1 -0
- package/dist/core/agent/agent-prompt.d.ts +0 -1
- package/dist/core/agent/agent-prompt.d.ts.map +1 -1
- package/dist/core/agent/agent-prompt.js +7 -15
- package/dist/core/agent/agent-prompt.js.map +1 -1
- package/dist/core/agent/agent-runner.d.ts +15 -0
- package/dist/core/agent/agent-runner.d.ts.map +1 -1
- package/dist/core/agent/agent-runner.js +570 -270
- package/dist/core/agent/agent-runner.js.map +1 -1
- package/dist/core/agent/agent-service.d.ts +20 -5
- package/dist/core/agent/agent-service.d.ts.map +1 -1
- package/dist/core/agent/agent-service.js +54 -6
- package/dist/core/agent/agent-service.js.map +1 -1
- package/dist/core/agent/gmail-agent.js +7 -7
- package/dist/core/agent/gmail-agent.js.map +1 -1
- package/dist/core/agent/prompts/coder/v1.d.ts +2 -0
- package/dist/core/agent/prompts/coder/v1.d.ts.map +1 -0
- package/dist/core/agent/prompts/coder/v1.js +370 -0
- package/dist/core/agent/prompts/coder/v1.js.map +1 -0
- package/dist/core/agent/prompts/default/v2.d.ts +1 -1
- package/dist/core/agent/prompts/default/v2.d.ts.map +1 -1
- package/dist/core/agent/prompts/default/v2.js +1 -2
- package/dist/core/agent/prompts/default/v2.js.map +1 -1
- package/dist/core/agent/prompts/gmail/v1.d.ts +1 -1
- package/dist/core/agent/prompts/gmail/v1.d.ts.map +1 -1
- package/dist/core/agent/prompts/gmail/v1.js +5 -5
- package/dist/core/agent/prompts/gmail/v2.d.ts +1 -1
- package/dist/core/agent/prompts/gmail/v2.d.ts.map +1 -1
- package/dist/core/agent/prompts/gmail/v2.js +7 -7
- package/dist/core/agent/tools/base-tool.d.ts +3 -4
- package/dist/core/agent/tools/base-tool.d.ts.map +1 -1
- package/dist/core/agent/tools/base-tool.js +11 -51
- package/dist/core/agent/tools/base-tool.js.map +1 -1
- package/dist/core/agent/tools/context-utils.d.ts +6 -0
- package/dist/core/agent/tools/context-utils.d.ts.map +1 -0
- package/dist/core/agent/tools/context-utils.js +9 -0
- package/dist/core/agent/tools/context-utils.js.map +1 -0
- package/dist/core/agent/tools/env-utils.d.ts +7 -0
- package/dist/core/agent/tools/env-utils.d.ts.map +1 -0
- package/dist/core/agent/tools/env-utils.js +39 -0
- package/dist/core/agent/tools/env-utils.js.map +1 -0
- package/dist/core/agent/tools/fs-tools.d.ts.map +1 -1
- package/dist/core/agent/tools/fs-tools.js +48 -53
- package/dist/core/agent/tools/fs-tools.js.map +1 -1
- package/dist/core/agent/tools/git-tools.d.ts +5 -0
- package/dist/core/agent/tools/git-tools.d.ts.map +1 -1
- package/dist/core/agent/tools/git-tools.js +716 -154
- package/dist/core/agent/tools/git-tools.js.map +1 -1
- package/dist/core/agent/tools/gmail-tools.js +35 -35
- package/dist/core/agent/tools/gmail-tools.js.map +1 -1
- package/dist/core/agent/tools/http-tools.js +2 -2
- package/dist/core/agent/tools/http-tools.js.map +1 -1
- package/dist/core/agent/tools/register-tools.d.ts +18 -1
- package/dist/core/agent/tools/register-tools.d.ts.map +1 -1
- package/dist/core/agent/tools/register-tools.js +52 -6
- package/dist/core/agent/tools/register-tools.js.map +1 -1
- package/dist/core/agent/tools/shell-tools.d.ts.map +1 -1
- package/dist/core/agent/tools/shell-tools.js +10 -20
- package/dist/core/agent/tools/shell-tools.js.map +1 -1
- package/dist/core/agent/tools/tool-registry.d.ts +11 -7
- package/dist/core/agent/tools/tool-registry.d.ts.map +1 -1
- package/dist/core/agent/tools/tool-registry.js +45 -19
- package/dist/core/agent/tools/tool-registry.js.map +1 -1
- package/dist/core/agent/tools/web-search-tools.js +1 -1
- package/dist/core/agent/tools/web-search-tools.js.map +1 -1
- package/dist/core/agent/tracking/agent-run-tracker.d.ts +2 -0
- package/dist/core/agent/tracking/agent-run-tracker.d.ts.map +1 -1
- package/dist/core/agent/tracking/agent-run-tracker.js +40 -2
- package/dist/core/agent/tracking/agent-run-tracker.js.map +1 -1
- package/dist/core/types/index.d.ts +82 -15
- package/dist/core/types/index.d.ts.map +1 -1
- package/dist/core/types/index.js.map +1 -1
- package/dist/core/utils/markdown-renderer.d.ts +25 -0
- package/dist/core/utils/markdown-renderer.d.ts.map +1 -1
- package/dist/core/utils/markdown-renderer.js +100 -1
- package/dist/core/utils/markdown-renderer.js.map +1 -1
- package/dist/core/utils/output-renderer.d.ts +81 -0
- package/dist/core/utils/output-renderer.d.ts.map +1 -0
- package/dist/core/utils/output-renderer.js +291 -0
- package/dist/core/utils/output-renderer.js.map +1 -0
- package/dist/core/utils/output-theme.d.ts +64 -0
- package/dist/core/utils/output-theme.d.ts.map +1 -0
- package/dist/core/utils/output-theme.js +154 -0
- package/dist/core/utils/output-theme.js.map +1 -0
- package/dist/core/utils/output-writer.d.ts +79 -0
- package/dist/core/utils/output-writer.d.ts.map +1 -0
- package/dist/core/utils/output-writer.js +133 -0
- package/dist/core/utils/output-writer.js.map +1 -0
- package/dist/core/utils/runtime-detection.d.ts +28 -0
- package/dist/core/utils/runtime-detection.d.ts.map +1 -0
- package/dist/core/utils/runtime-detection.js +62 -0
- package/dist/core/utils/runtime-detection.js.map +1 -0
- package/dist/core/utils/string.d.ts +8 -0
- package/dist/core/utils/string.d.ts.map +1 -0
- package/dist/core/utils/string.js +19 -0
- package/dist/core/utils/string.js.map +1 -0
- package/dist/core/utils/thinking-renderer.d.ts +56 -0
- package/dist/core/utils/thinking-renderer.d.ts.map +1 -0
- package/dist/core/utils/thinking-renderer.js +174 -0
- package/dist/core/utils/thinking-renderer.js.map +1 -0
- package/dist/core/utils/tool-formatter.d.ts +21 -0
- package/dist/core/utils/tool-formatter.d.ts.map +1 -0
- package/dist/core/utils/tool-formatter.js +343 -0
- package/dist/core/utils/tool-formatter.js.map +1 -0
- package/dist/main.js +11 -4
- package/dist/main.js.map +1 -1
- package/dist/services/config.d.ts.map +1 -1
- package/dist/services/config.js +20 -20
- package/dist/services/config.js.map +1 -1
- package/dist/services/llm/ai-sdk-service.d.ts.map +1 -1
- package/dist/services/llm/ai-sdk-service.js +128 -37
- package/dist/services/llm/ai-sdk-service.js.map +1 -1
- package/dist/services/llm/stream-detector.d.ts +44 -0
- package/dist/services/llm/stream-detector.d.ts.map +1 -0
- package/dist/services/llm/stream-detector.js +81 -0
- package/dist/services/llm/stream-detector.js.map +1 -0
- package/dist/services/llm/stream-processor.d.ts +93 -0
- package/dist/services/llm/stream-processor.d.ts.map +1 -0
- package/dist/services/llm/stream-processor.js +330 -0
- package/dist/services/llm/stream-processor.js.map +1 -0
- package/dist/services/llm/streaming-types.d.ts +131 -0
- package/dist/services/llm/streaming-types.d.ts.map +1 -0
- package/dist/services/llm/streaming-types.js +12 -0
- package/dist/services/llm/streaming-types.js.map +1 -0
- package/dist/services/llm/types.d.ts +8 -0
- package/dist/services/llm/types.d.ts.map +1 -1
- package/dist/services/llm/types.js.map +1 -1
- package/dist/services/logger.d.ts +4 -4
- package/dist/services/logger.d.ts.map +1 -1
- package/dist/services/logger.js +23 -45
- package/dist/services/logger.js.map +1 -1
- package/dist/services/shell.d.ts.map +1 -1
- package/dist/services/shell.js +52 -18
- package/dist/services/shell.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,19 +1,107 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.createGitStatusTool = createGitStatusTool;
|
|
4
37
|
exports.createGitLogTool = createGitLogTool;
|
|
5
38
|
exports.createGitDiffTool = createGitDiffTool;
|
|
6
39
|
exports.createGitBranchTool = createGitBranchTool;
|
|
7
40
|
exports.createGitAddTool = createGitAddTool;
|
|
41
|
+
exports.createExecuteGitAddTool = createExecuteGitAddTool;
|
|
8
42
|
exports.createGitCommitTool = createGitCommitTool;
|
|
43
|
+
exports.createExecuteGitCommitTool = createExecuteGitCommitTool;
|
|
9
44
|
exports.createGitPushTool = createGitPushTool;
|
|
10
45
|
exports.createGitPullTool = createGitPullTool;
|
|
11
46
|
exports.createGitCheckoutTool = createGitCheckoutTool;
|
|
47
|
+
exports.createExecuteGitPushTool = createExecuteGitPushTool;
|
|
48
|
+
exports.createExecuteGitPullTool = createExecuteGitPullTool;
|
|
49
|
+
exports.createExecuteGitCheckoutTool = createExecuteGitCheckoutTool;
|
|
12
50
|
const effect_1 = require("effect");
|
|
13
51
|
const zod_1 = require("zod");
|
|
14
52
|
const shell_1 = require("../../../services/shell");
|
|
15
53
|
const base_tool_1 = require("./base-tool");
|
|
16
|
-
|
|
54
|
+
const context_utils_1 = require("./context-utils");
|
|
55
|
+
const env_utils_1 = require("./env-utils");
|
|
56
|
+
const DEFAULT_GIT_TIMEOUT = 15000;
|
|
57
|
+
function runGitCommand(options) {
|
|
58
|
+
return effect_1.Effect.gen(function* () {
|
|
59
|
+
const { spawn } = yield* effect_1.Effect.promise(() => Promise.resolve().then(() => __importStar(require("child_process"))));
|
|
60
|
+
return yield* effect_1.Effect.async((resume) => {
|
|
61
|
+
const sanitizedEnv = (0, env_utils_1.createSanitizedEnv)();
|
|
62
|
+
const gitArgs = ["--no-pager", ...options.args];
|
|
63
|
+
const child = spawn("git", gitArgs, {
|
|
64
|
+
cwd: options.workingDirectory,
|
|
65
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
66
|
+
env: sanitizedEnv,
|
|
67
|
+
detached: false,
|
|
68
|
+
});
|
|
69
|
+
let stdout = "";
|
|
70
|
+
let stderr = "";
|
|
71
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_GIT_TIMEOUT;
|
|
72
|
+
const timeoutId = setTimeout(() => {
|
|
73
|
+
child.kill("SIGTERM");
|
|
74
|
+
resume(effect_1.Effect.fail(new Error(`Git command timed out after ${timeoutMs}ms`)));
|
|
75
|
+
}, timeoutMs);
|
|
76
|
+
child.stdout.on("data", (data) => {
|
|
77
|
+
stdout += data.toString();
|
|
78
|
+
});
|
|
79
|
+
child.stderr.on("data", (data) => {
|
|
80
|
+
stderr += data.toString();
|
|
81
|
+
});
|
|
82
|
+
child.on("error", (error) => {
|
|
83
|
+
clearTimeout(timeoutId);
|
|
84
|
+
resume(effect_1.Effect.fail(error));
|
|
85
|
+
});
|
|
86
|
+
child.on("close", (code) => {
|
|
87
|
+
clearTimeout(timeoutId);
|
|
88
|
+
resume(effect_1.Effect.succeed({
|
|
89
|
+
stdout: stdout.trimEnd(),
|
|
90
|
+
stderr: stderr.trimEnd(),
|
|
91
|
+
exitCode: code ?? 0,
|
|
92
|
+
}));
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
function resolveWorkingDirectory(shell, context, path) {
|
|
98
|
+
const key = (0, context_utils_1.buildKeyFromContext)(context);
|
|
99
|
+
if (path && path.trim().length > 0) {
|
|
100
|
+
return shell.resolvePath(key, path);
|
|
101
|
+
}
|
|
102
|
+
return shell.getCwd(key);
|
|
103
|
+
}
|
|
104
|
+
// Safe Git operations (no approval needed) \\
|
|
17
105
|
function createGitStatusTool() {
|
|
18
106
|
const parameters = zod_1.z
|
|
19
107
|
.object({
|
|
@@ -24,8 +112,8 @@ function createGitStatusTool() {
|
|
|
24
112
|
})
|
|
25
113
|
.strict();
|
|
26
114
|
return (0, base_tool_1.defineTool)({
|
|
27
|
-
name: "
|
|
28
|
-
description: "
|
|
115
|
+
name: "git_status",
|
|
116
|
+
description: "Display the current status of a Git repository's working tree. Shows modified files, untracked files, staged changes, and current branch information. Use this to understand what changes exist before committing or to check repository state.",
|
|
29
117
|
tags: ["git", "status"],
|
|
30
118
|
parameters,
|
|
31
119
|
validate: (args) => {
|
|
@@ -37,29 +125,53 @@ function createGitStatusTool() {
|
|
|
37
125
|
handler: (args, context) => effect_1.Effect.gen(function* () {
|
|
38
126
|
const shell = yield* shell_1.FileSystemContextServiceTag;
|
|
39
127
|
const typedArgs = args;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
128
|
+
// Catch errors from path resolution and return them as ToolExecutionResult
|
|
129
|
+
const workingDirResult = yield* resolveWorkingDirectory(shell, context, typedArgs.path).pipe(effect_1.Effect.catchAll((error) => effect_1.Effect.succeed({
|
|
130
|
+
success: false,
|
|
131
|
+
result: null,
|
|
132
|
+
error: error instanceof Error ? error.message : String(error),
|
|
133
|
+
})));
|
|
134
|
+
// If path resolution failed, return the error
|
|
135
|
+
if (typeof workingDirResult === "object" &&
|
|
136
|
+
"success" in workingDirResult &&
|
|
137
|
+
!workingDirResult.success) {
|
|
138
|
+
return workingDirResult;
|
|
139
|
+
}
|
|
140
|
+
const workingDir = workingDirResult;
|
|
141
|
+
const commandResult = yield* runGitCommand({
|
|
142
|
+
args: ["status", "--short", "--branch"],
|
|
143
|
+
workingDirectory: workingDir,
|
|
144
|
+
});
|
|
145
|
+
if (commandResult.exitCode !== 0) {
|
|
146
|
+
return {
|
|
147
|
+
success: false,
|
|
148
|
+
result: null,
|
|
149
|
+
error: commandResult.stderr ||
|
|
150
|
+
`git status failed with exit code ${commandResult.exitCode}`,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
const lines = commandResult.stdout.split("\n").filter((line) => line.trim().length > 0);
|
|
154
|
+
const branchLine = lines.find((line) => line.startsWith("##")) ?? "";
|
|
155
|
+
const changes = lines.filter((line) => !line.startsWith("##"));
|
|
156
|
+
const hasChanges = changes.length > 0;
|
|
50
157
|
return {
|
|
51
158
|
success: true,
|
|
52
159
|
result: {
|
|
53
160
|
workingDirectory: workingDir,
|
|
54
|
-
|
|
55
|
-
hasChanges
|
|
161
|
+
branch: branchLine.replace(/^##\s*/, "") || "unknown",
|
|
162
|
+
hasChanges,
|
|
163
|
+
summary: hasChanges ? changes : ["Working tree clean"],
|
|
164
|
+
rawStatus: commandResult.stdout,
|
|
56
165
|
},
|
|
57
166
|
};
|
|
58
167
|
}),
|
|
59
168
|
createSummary: (result) => {
|
|
60
169
|
if (result.success && typeof result.result === "object" && result.result !== null) {
|
|
61
170
|
const gitResult = result.result;
|
|
62
|
-
|
|
171
|
+
const suffix = gitResult.branch ? ` on ${gitResult.branch}` : "";
|
|
172
|
+
return gitResult.hasChanges
|
|
173
|
+
? `Repository has changes${suffix}`
|
|
174
|
+
: `Repository is clean${suffix}`;
|
|
63
175
|
}
|
|
64
176
|
return result.success ? "Git status retrieved" : "Git status failed";
|
|
65
177
|
},
|
|
@@ -83,8 +195,8 @@ function createGitLogTool() {
|
|
|
83
195
|
})
|
|
84
196
|
.strict();
|
|
85
197
|
return (0, base_tool_1.defineTool)({
|
|
86
|
-
name: "
|
|
87
|
-
description: "
|
|
198
|
+
name: "git_log",
|
|
199
|
+
description: "Display commit history of a Git repository. Shows commit hashes, authors, dates, and messages. Supports limiting results and one-line format for quick overview. Use to review recent changes, find specific commits, or understand repository evolution.",
|
|
88
200
|
tags: ["git", "history"],
|
|
89
201
|
parameters,
|
|
90
202
|
validate: (args) => {
|
|
@@ -96,22 +208,59 @@ function createGitLogTool() {
|
|
|
96
208
|
handler: (args, context) => effect_1.Effect.gen(function* () {
|
|
97
209
|
const shell = yield* shell_1.FileSystemContextServiceTag;
|
|
98
210
|
const typedArgs = args;
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
211
|
+
// Catch errors from path resolution and return them as ToolExecutionResult
|
|
212
|
+
const workingDirResult = yield* resolveWorkingDirectory(shell, context, typedArgs.path).pipe(effect_1.Effect.catchAll((error) => effect_1.Effect.succeed({
|
|
213
|
+
success: false,
|
|
214
|
+
result: null,
|
|
215
|
+
error: error instanceof Error ? error.message : String(error),
|
|
216
|
+
})));
|
|
217
|
+
// If path resolution failed, return the error
|
|
218
|
+
if (typeof workingDirResult === "object" &&
|
|
219
|
+
"success" in workingDirResult &&
|
|
220
|
+
!workingDirResult.success) {
|
|
221
|
+
return workingDirResult;
|
|
222
|
+
}
|
|
223
|
+
const workingDir = workingDirResult;
|
|
224
|
+
const limit = typedArgs.limit ?? 10;
|
|
225
|
+
const prettyFormat = "%H%x1f%h%x1f%an%x1f%ar%x1f%s%x1e";
|
|
226
|
+
const commandResult = yield* runGitCommand({
|
|
227
|
+
args: [
|
|
228
|
+
"log",
|
|
229
|
+
`--max-count=${limit}`,
|
|
230
|
+
`--pretty=format:${prettyFormat}`,
|
|
231
|
+
"--date=relative",
|
|
232
|
+
],
|
|
233
|
+
workingDirectory: workingDir,
|
|
234
|
+
});
|
|
235
|
+
if (commandResult.exitCode !== 0) {
|
|
236
|
+
return {
|
|
237
|
+
success: false,
|
|
238
|
+
result: null,
|
|
239
|
+
error: commandResult.stderr || `git log failed with exit code ${commandResult.exitCode}`,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
const commits = commandResult.stdout
|
|
243
|
+
.split("\x1e")
|
|
244
|
+
.filter((entry) => entry.trim().length > 0)
|
|
245
|
+
.map((entry) => {
|
|
246
|
+
const [hash, shortHash, author, relativeDate, subject] = entry
|
|
247
|
+
.split("\x1f")
|
|
248
|
+
.map((value) => value.trim());
|
|
249
|
+
return {
|
|
250
|
+
hash,
|
|
251
|
+
shortHash,
|
|
252
|
+
author,
|
|
253
|
+
relativeDate,
|
|
254
|
+
subject,
|
|
255
|
+
oneline: typedArgs.oneline ? `${shortHash} ${subject}` : undefined,
|
|
256
|
+
};
|
|
257
|
+
});
|
|
109
258
|
return {
|
|
110
259
|
success: true,
|
|
111
260
|
result: {
|
|
112
261
|
workingDirectory: workingDir,
|
|
113
|
-
|
|
114
|
-
|
|
262
|
+
commitCount: commits.length,
|
|
263
|
+
commits,
|
|
115
264
|
},
|
|
116
265
|
};
|
|
117
266
|
}),
|
|
@@ -137,8 +286,8 @@ function createGitDiffTool() {
|
|
|
137
286
|
})
|
|
138
287
|
.strict();
|
|
139
288
|
return (0, base_tool_1.defineTool)({
|
|
140
|
-
name: "
|
|
141
|
-
description: "
|
|
289
|
+
name: "git_diff",
|
|
290
|
+
description: "Display differences between commits, branches, or working tree. Shows what has changed in files (additions, deletions, modifications). Use to review changes before committing, compare branches, or see what differs from a specific commit. Supports staged changes and branch comparisons.",
|
|
142
291
|
tags: ["git", "diff"],
|
|
143
292
|
parameters,
|
|
144
293
|
validate: (args) => {
|
|
@@ -150,24 +299,51 @@ function createGitDiffTool() {
|
|
|
150
299
|
handler: (args, context) => effect_1.Effect.gen(function* () {
|
|
151
300
|
const shell = yield* shell_1.FileSystemContextServiceTag;
|
|
152
301
|
const typedArgs = args;
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
302
|
+
// Catch errors from path resolution and return them as ToolExecutionResult
|
|
303
|
+
const workingDirResult = yield* resolveWorkingDirectory(shell, context, typedArgs.path).pipe(effect_1.Effect.catchAll((error) => effect_1.Effect.succeed({
|
|
304
|
+
success: false,
|
|
305
|
+
result: null,
|
|
306
|
+
error: error instanceof Error ? error.message : String(error),
|
|
307
|
+
})));
|
|
308
|
+
// If path resolution failed, return the error
|
|
309
|
+
if (typeof workingDirResult === "object" &&
|
|
310
|
+
"success" in workingDirResult &&
|
|
311
|
+
!workingDirResult.success) {
|
|
312
|
+
return workingDirResult;
|
|
313
|
+
}
|
|
314
|
+
const workingDir = workingDirResult;
|
|
315
|
+
const diffArgs = ["diff", "--no-color"];
|
|
316
|
+
if (typedArgs.staged) {
|
|
317
|
+
diffArgs.push("--staged");
|
|
318
|
+
}
|
|
319
|
+
if (typedArgs.branch) {
|
|
320
|
+
diffArgs.push(typedArgs.branch);
|
|
321
|
+
}
|
|
322
|
+
else if (typedArgs.commit) {
|
|
323
|
+
diffArgs.push(typedArgs.commit);
|
|
324
|
+
}
|
|
325
|
+
const commandResult = yield* runGitCommand({
|
|
326
|
+
args: diffArgs,
|
|
327
|
+
workingDirectory: workingDir,
|
|
328
|
+
timeoutMs: 20000,
|
|
329
|
+
});
|
|
330
|
+
if (commandResult.exitCode !== 0) {
|
|
331
|
+
return {
|
|
332
|
+
success: false,
|
|
333
|
+
result: null,
|
|
334
|
+
error: commandResult.stderr || `git diff failed with exit code ${commandResult.exitCode}`,
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
const trimmedDiff = commandResult.stdout.trimEnd();
|
|
338
|
+
const hasChanges = trimmedDiff.length > 0;
|
|
163
339
|
return {
|
|
164
340
|
success: true,
|
|
165
341
|
result: {
|
|
166
342
|
workingDirectory: workingDir,
|
|
167
|
-
diff:
|
|
168
|
-
hasChanges
|
|
343
|
+
diff: trimmedDiff || "No differences",
|
|
344
|
+
hasChanges,
|
|
169
345
|
options: {
|
|
170
|
-
staged: typedArgs.staged
|
|
346
|
+
staged: typedArgs.staged ?? false,
|
|
171
347
|
branch: typedArgs.branch,
|
|
172
348
|
commit: typedArgs.commit,
|
|
173
349
|
},
|
|
@@ -196,8 +372,8 @@ function createGitBranchTool() {
|
|
|
196
372
|
})
|
|
197
373
|
.strict();
|
|
198
374
|
return (0, base_tool_1.defineTool)({
|
|
199
|
-
name: "
|
|
200
|
-
description: "List,
|
|
375
|
+
name: "git_branch",
|
|
376
|
+
description: "List Git branches (local, remote, or both). Shows all available branches and identifies the current branch. Use to see what branches exist, check which branch you're on, or discover remote branches. Note: This tool only lists branches; use git_checkout to switch branches.",
|
|
201
377
|
tags: ["git", "branch"],
|
|
202
378
|
parameters,
|
|
203
379
|
validate: (args) => {
|
|
@@ -209,26 +385,56 @@ function createGitBranchTool() {
|
|
|
209
385
|
handler: (args, context) => effect_1.Effect.gen(function* () {
|
|
210
386
|
const shell = yield* shell_1.FileSystemContextServiceTag;
|
|
211
387
|
const typedArgs = args;
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
388
|
+
// Catch errors from path resolution and return them as ToolExecutionResult
|
|
389
|
+
const workingDirResult = yield* resolveWorkingDirectory(shell, context, typedArgs.path).pipe(effect_1.Effect.catchAll((error) => effect_1.Effect.succeed({
|
|
390
|
+
success: false,
|
|
391
|
+
result: null,
|
|
392
|
+
error: error instanceof Error ? error.message : String(error),
|
|
393
|
+
})));
|
|
394
|
+
// If path resolution failed, return the error
|
|
395
|
+
if (typeof workingDirResult === "object" &&
|
|
396
|
+
"success" in workingDirResult &&
|
|
397
|
+
!workingDirResult.success) {
|
|
398
|
+
return workingDirResult;
|
|
399
|
+
}
|
|
400
|
+
const workingDir = workingDirResult;
|
|
401
|
+
const branchArgs = ["branch", "--list"];
|
|
402
|
+
if (typedArgs.remote) {
|
|
403
|
+
branchArgs.push("--remotes");
|
|
404
|
+
}
|
|
405
|
+
else if (typedArgs.all) {
|
|
406
|
+
branchArgs.push("--all");
|
|
407
|
+
}
|
|
408
|
+
const commandResult = yield* runGitCommand({
|
|
409
|
+
args: branchArgs,
|
|
410
|
+
workingDirectory: workingDir,
|
|
411
|
+
});
|
|
412
|
+
if (commandResult.exitCode !== 0) {
|
|
413
|
+
return {
|
|
414
|
+
success: false,
|
|
415
|
+
result: null,
|
|
416
|
+
error: commandResult.stderr || `git branch failed with exit code ${commandResult.exitCode}`,
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
const lines = commandResult.stdout.split("\n").filter((line) => line.trim().length > 0);
|
|
420
|
+
let currentBranch;
|
|
421
|
+
const branches = lines.map((line) => {
|
|
422
|
+
const trimmed = line.replace(/^\*\s*/, "").trim();
|
|
423
|
+
if (line.trim().startsWith("*")) {
|
|
424
|
+
currentBranch = trimmed;
|
|
425
|
+
}
|
|
426
|
+
return trimmed;
|
|
427
|
+
});
|
|
222
428
|
return {
|
|
223
429
|
success: true,
|
|
224
430
|
result: {
|
|
225
431
|
workingDirectory: workingDir,
|
|
226
|
-
branches
|
|
227
|
-
currentBranch
|
|
432
|
+
branches,
|
|
433
|
+
currentBranch,
|
|
228
434
|
options: {
|
|
229
435
|
list: typedArgs.list !== false,
|
|
230
|
-
all: typedArgs.all
|
|
231
|
-
remote: typedArgs.remote
|
|
436
|
+
all: typedArgs.all ?? false,
|
|
437
|
+
remote: typedArgs.remote ?? false,
|
|
232
438
|
},
|
|
233
439
|
},
|
|
234
440
|
};
|
|
@@ -255,8 +461,8 @@ function createGitAddTool() {
|
|
|
255
461
|
})
|
|
256
462
|
.strict();
|
|
257
463
|
return (0, base_tool_1.defineTool)({
|
|
258
|
-
name: "
|
|
259
|
-
description: "
|
|
464
|
+
name: "git_add",
|
|
465
|
+
description: "Stage files for commit by adding them to Git's index. Prepares changes to be included in the next commit. Can stage specific files or all changes. Requires user approval before execution.",
|
|
260
466
|
tags: ["git", "index"],
|
|
261
467
|
parameters,
|
|
262
468
|
validate: (args) => {
|
|
@@ -279,28 +485,95 @@ function createGitAddTool() {
|
|
|
279
485
|
...(context.conversationId && { conversationId: context.conversationId }),
|
|
280
486
|
});
|
|
281
487
|
const filesToAdd = typedArgs.all ? "all files" : typedArgs.files.join(", ");
|
|
282
|
-
return `Add ${filesToAdd} to Git staging area in ${workingDir}
|
|
488
|
+
return `Add ${filesToAdd} to Git staging area in ${workingDir}?\n\nIMPORTANT: After getting user confirmation, you MUST call the execute_git_add tool with these exact arguments: {"path": ${typedArgs.path ? `"${typedArgs.path}"` : "undefined"}, "files": ${JSON.stringify(typedArgs.files)}, "all": ${typedArgs.all === true}}`;
|
|
283
489
|
}),
|
|
490
|
+
errorMessage: "Approval required: Git add requires user confirmation.",
|
|
491
|
+
execute: {
|
|
492
|
+
toolName: "execute_git_add",
|
|
493
|
+
buildArgs: (args) => {
|
|
494
|
+
const typedArgs = args;
|
|
495
|
+
return {
|
|
496
|
+
path: typedArgs.path,
|
|
497
|
+
files: typedArgs.files,
|
|
498
|
+
all: typedArgs.all,
|
|
499
|
+
};
|
|
500
|
+
},
|
|
501
|
+
},
|
|
502
|
+
},
|
|
503
|
+
handler: (_args, _context) => effect_1.Effect.succeed({
|
|
504
|
+
success: false,
|
|
505
|
+
result: null,
|
|
506
|
+
error: "Approval required",
|
|
507
|
+
}),
|
|
508
|
+
createSummary: (result) => {
|
|
509
|
+
if (result.success && typeof result.result === "object" && result.result !== null) {
|
|
510
|
+
const gitResult = result.result;
|
|
511
|
+
return `Added ${Array.isArray(gitResult.addedFiles) ? gitResult.addedFiles.join(", ") : gitResult.addedFiles} to staging area`;
|
|
512
|
+
}
|
|
513
|
+
return result.success ? "Files added to Git" : "Git add failed";
|
|
514
|
+
},
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
function createExecuteGitAddTool() {
|
|
518
|
+
const parameters = zod_1.z
|
|
519
|
+
.object({
|
|
520
|
+
path: zod_1.z
|
|
521
|
+
.string()
|
|
522
|
+
.optional()
|
|
523
|
+
.describe("Path to the Git repository (defaults to current working directory)"),
|
|
524
|
+
files: zod_1.z.array(zod_1.z.string()).min(1).describe("Files to add to the staging area"),
|
|
525
|
+
all: zod_1.z.boolean().optional().describe("Add all changes in the working directory"),
|
|
526
|
+
})
|
|
527
|
+
.strict();
|
|
528
|
+
return (0, base_tool_1.defineTool)({
|
|
529
|
+
name: "execute_git_add",
|
|
530
|
+
description: "Internal tool that performs the actual git add operation after user has approved the git_add request. Stages files for commit by adding them to Git's index.",
|
|
531
|
+
hidden: true,
|
|
532
|
+
parameters,
|
|
533
|
+
validate: (args) => {
|
|
534
|
+
const result = parameters.safeParse(args);
|
|
535
|
+
return result.success
|
|
536
|
+
? { valid: true, value: result.data }
|
|
537
|
+
: { valid: false, errors: result.error.issues.map((i) => i.message) };
|
|
284
538
|
},
|
|
285
539
|
handler: (args, context) => effect_1.Effect.gen(function* () {
|
|
286
540
|
const shell = yield* shell_1.FileSystemContextServiceTag;
|
|
287
541
|
const typedArgs = args;
|
|
288
|
-
const
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
542
|
+
const workingDirResult = yield* resolveWorkingDirectory(shell, context, typedArgs.path).pipe(effect_1.Effect.catchAll((error) => effect_1.Effect.succeed({
|
|
543
|
+
success: false,
|
|
544
|
+
result: null,
|
|
545
|
+
error: error instanceof Error ? error.message : String(error),
|
|
546
|
+
})));
|
|
547
|
+
if (typeof workingDirResult === "object" &&
|
|
548
|
+
"success" in workingDirResult &&
|
|
549
|
+
!workingDirResult.success) {
|
|
550
|
+
return workingDirResult;
|
|
551
|
+
}
|
|
552
|
+
const workingDir = workingDirResult;
|
|
553
|
+
const addArgs = ["add"];
|
|
554
|
+
if (typedArgs.all) {
|
|
555
|
+
addArgs.push("--all");
|
|
556
|
+
}
|
|
557
|
+
else {
|
|
558
|
+
addArgs.push(...typedArgs.files);
|
|
559
|
+
}
|
|
560
|
+
const commandResult = yield* runGitCommand({
|
|
561
|
+
args: addArgs,
|
|
562
|
+
workingDirectory: workingDir,
|
|
563
|
+
});
|
|
564
|
+
if (commandResult.exitCode !== 0) {
|
|
565
|
+
return {
|
|
566
|
+
success: false,
|
|
567
|
+
result: null,
|
|
568
|
+
error: commandResult.stderr || `git add failed with exit code ${commandResult.exitCode}`,
|
|
569
|
+
};
|
|
570
|
+
}
|
|
298
571
|
return {
|
|
299
572
|
success: true,
|
|
300
573
|
result: {
|
|
301
574
|
workingDirectory: workingDir,
|
|
302
575
|
addedFiles: typedArgs.all ? "all files" : typedArgs.files,
|
|
303
|
-
message: "Files
|
|
576
|
+
message: "Files added to staging area",
|
|
304
577
|
},
|
|
305
578
|
};
|
|
306
579
|
}),
|
|
@@ -325,8 +598,8 @@ function createGitCommitTool() {
|
|
|
325
598
|
})
|
|
326
599
|
.strict();
|
|
327
600
|
return (0, base_tool_1.defineTool)({
|
|
328
|
-
name: "
|
|
329
|
-
description: "
|
|
601
|
+
name: "git_commit",
|
|
602
|
+
description: "Create a commit to permanently record staged changes in the repository history. Requires a commit message describing the changes. Can commit all staged changes or all working directory changes. Requires user approval before execution.",
|
|
330
603
|
tags: ["git", "commit"],
|
|
331
604
|
parameters,
|
|
332
605
|
validate: (args) => {
|
|
@@ -348,28 +621,98 @@ function createGitCommitTool() {
|
|
|
348
621
|
agentId: context.agentId,
|
|
349
622
|
...(context.conversationId && { conversationId: context.conversationId }),
|
|
350
623
|
});
|
|
351
|
-
return `Commit changes in ${workingDir} with message: "${typedArgs.message}"
|
|
624
|
+
return `Commit changes in ${workingDir} with message: "${typedArgs.message}"?\n\nIMPORTANT: After getting user confirmation, you MUST call the execute_git_commit tool with these exact arguments: {"path": ${typedArgs.path ? `"${typedArgs.path}"` : "undefined"}, "message": ${JSON.stringify(typedArgs.message)}, "all": ${typedArgs.all === true}}`;
|
|
352
625
|
}),
|
|
626
|
+
errorMessage: "Approval required: Git commit requires user confirmation.",
|
|
627
|
+
execute: {
|
|
628
|
+
toolName: "execute_git_commit",
|
|
629
|
+
buildArgs: (args) => {
|
|
630
|
+
const typedArgs = args;
|
|
631
|
+
return {
|
|
632
|
+
path: typedArgs.path,
|
|
633
|
+
message: typedArgs.message,
|
|
634
|
+
all: typedArgs.all,
|
|
635
|
+
};
|
|
636
|
+
},
|
|
637
|
+
},
|
|
638
|
+
},
|
|
639
|
+
handler: (_args, _context) => effect_1.Effect.succeed({
|
|
640
|
+
success: false,
|
|
641
|
+
result: null,
|
|
642
|
+
error: "Approval required",
|
|
643
|
+
}),
|
|
644
|
+
createSummary: (result) => {
|
|
645
|
+
if (result.success && typeof result.result === "object" && result.result !== null) {
|
|
646
|
+
const gitResult = result.result;
|
|
647
|
+
return `Committed: "${gitResult.message}" (${gitResult.commitHash})`;
|
|
648
|
+
}
|
|
649
|
+
return result.success ? "Git commit created" : "Git commit failed";
|
|
650
|
+
},
|
|
651
|
+
});
|
|
652
|
+
}
|
|
653
|
+
function createExecuteGitCommitTool() {
|
|
654
|
+
const parameters = zod_1.z
|
|
655
|
+
.object({
|
|
656
|
+
path: zod_1.z
|
|
657
|
+
.string()
|
|
658
|
+
.optional()
|
|
659
|
+
.describe("Path to the Git repository (defaults to current working directory)"),
|
|
660
|
+
message: zod_1.z.string().min(1).describe("Commit message"),
|
|
661
|
+
all: zod_1.z.boolean().optional().describe("Commit all changes in the working directory"),
|
|
662
|
+
})
|
|
663
|
+
.strict();
|
|
664
|
+
return (0, base_tool_1.defineTool)({
|
|
665
|
+
name: "execute_git_commit",
|
|
666
|
+
description: "Internal tool that performs the actual git commit operation after user has approved the git_commit request. Creates a commit with the specified message.",
|
|
667
|
+
hidden: true,
|
|
668
|
+
parameters,
|
|
669
|
+
validate: (args) => {
|
|
670
|
+
const result = parameters.safeParse(args);
|
|
671
|
+
return result.success
|
|
672
|
+
? { valid: true, value: result.data }
|
|
673
|
+
: { valid: false, errors: result.error.issues.map((i) => i.message) };
|
|
353
674
|
},
|
|
354
675
|
handler: (args, context) => effect_1.Effect.gen(function* () {
|
|
355
676
|
const shell = yield* shell_1.FileSystemContextServiceTag;
|
|
356
677
|
const typedArgs = args;
|
|
357
|
-
const
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
678
|
+
const workingDirResult = yield* resolveWorkingDirectory(shell, context, typedArgs.path).pipe(effect_1.Effect.catchAll((error) => effect_1.Effect.succeed({
|
|
679
|
+
success: false,
|
|
680
|
+
result: null,
|
|
681
|
+
error: error instanceof Error ? error.message : String(error),
|
|
682
|
+
})));
|
|
683
|
+
if (typeof workingDirResult === "object" &&
|
|
684
|
+
"success" in workingDirResult &&
|
|
685
|
+
!workingDirResult.success) {
|
|
686
|
+
return workingDirResult;
|
|
687
|
+
}
|
|
688
|
+
const workingDir = workingDirResult;
|
|
689
|
+
const commitArgs = ["commit", "-m", typedArgs.message];
|
|
690
|
+
if (typedArgs.all) {
|
|
691
|
+
commitArgs.push("--all");
|
|
692
|
+
}
|
|
693
|
+
const commandResult = yield* runGitCommand({
|
|
694
|
+
args: commitArgs,
|
|
695
|
+
workingDirectory: workingDir,
|
|
696
|
+
});
|
|
697
|
+
if (commandResult.exitCode !== 0) {
|
|
698
|
+
return {
|
|
699
|
+
success: false,
|
|
700
|
+
result: null,
|
|
701
|
+
error: commandResult.stderr || `git commit failed with exit code ${commandResult.exitCode}`,
|
|
702
|
+
};
|
|
703
|
+
}
|
|
704
|
+
// Get the commit hash from the last commit
|
|
705
|
+
const hashResult = yield* runGitCommand({
|
|
706
|
+
args: ["rev-parse", "HEAD"],
|
|
707
|
+
workingDirectory: workingDir,
|
|
708
|
+
});
|
|
709
|
+
const commitHash = hashResult.exitCode === 0 ? hashResult.stdout.trim() : "unknown";
|
|
367
710
|
return {
|
|
368
711
|
success: true,
|
|
369
712
|
result: {
|
|
370
713
|
workingDirectory: workingDir,
|
|
371
714
|
message: typedArgs.message,
|
|
372
|
-
commitHash
|
|
715
|
+
commitHash,
|
|
373
716
|
},
|
|
374
717
|
};
|
|
375
718
|
}),
|
|
@@ -395,8 +738,8 @@ function createGitPushTool() {
|
|
|
395
738
|
})
|
|
396
739
|
.strict();
|
|
397
740
|
return (0, base_tool_1.defineTool)({
|
|
398
|
-
name: "
|
|
399
|
-
description: "
|
|
741
|
+
name: "git_push",
|
|
742
|
+
description: "Upload local commits to a remote repository. Pushes the current branch (or specified branch) to the remote (default: origin). Supports force push to overwrite remote history (use with caution). Requires user approval before execution.",
|
|
400
743
|
tags: ["git", "push"],
|
|
401
744
|
parameters,
|
|
402
745
|
validate: (args) => {
|
|
@@ -421,32 +764,26 @@ function createGitPushTool() {
|
|
|
421
764
|
const remote = typedArgs.remote || "origin";
|
|
422
765
|
const branch = typedArgs.branch || "current branch";
|
|
423
766
|
const force = typedArgs.force ? " (force push)" : "";
|
|
424
|
-
return `Push${force} to ${remote}/${branch} in ${workingDir}
|
|
767
|
+
return `Push${force} to ${remote}/${branch} in ${workingDir}?\n\nIMPORTANT: After getting user confirmation, you MUST call the execute_git_push tool with these exact arguments: {"path": ${typedArgs.path ? `"${typedArgs.path}"` : "undefined"}, "remote": ${typedArgs.remote ? `"${typedArgs.remote}"` : "undefined"}, "branch": ${typedArgs.branch ? `"${typedArgs.branch}"` : "undefined"}, "force": ${typedArgs.force === true}}`;
|
|
425
768
|
}),
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
...(context.conversationId && { conversationId: context.conversationId }),
|
|
438
|
-
});
|
|
439
|
-
// For now, return a simple push message
|
|
440
|
-
return {
|
|
441
|
-
success: true,
|
|
442
|
-
result: {
|
|
443
|
-
workingDirectory: workingDir,
|
|
444
|
-
remote: typedArgs.remote || "origin",
|
|
445
|
-
branch: typedArgs.branch || "current",
|
|
446
|
-
force: typedArgs.force || false,
|
|
447
|
-
message: "Changes would be pushed successfully",
|
|
769
|
+
errorMessage: "Approval required: Git push requires user confirmation.",
|
|
770
|
+
execute: {
|
|
771
|
+
toolName: "execute_git_push",
|
|
772
|
+
buildArgs: (args) => {
|
|
773
|
+
const typedArgs = args;
|
|
774
|
+
return {
|
|
775
|
+
path: typedArgs.path,
|
|
776
|
+
remote: typedArgs.remote,
|
|
777
|
+
branch: typedArgs.branch,
|
|
778
|
+
force: typedArgs.force,
|
|
779
|
+
};
|
|
448
780
|
},
|
|
449
|
-
}
|
|
781
|
+
},
|
|
782
|
+
},
|
|
783
|
+
handler: (_args, _context) => effect_1.Effect.succeed({
|
|
784
|
+
success: false,
|
|
785
|
+
result: null,
|
|
786
|
+
error: "Approval required",
|
|
450
787
|
}),
|
|
451
788
|
createSummary: (result) => {
|
|
452
789
|
if (result.success && typeof result.result === "object" && result.result !== null) {
|
|
@@ -470,8 +807,8 @@ function createGitPullTool() {
|
|
|
470
807
|
})
|
|
471
808
|
.strict();
|
|
472
809
|
return (0, base_tool_1.defineTool)({
|
|
473
|
-
name: "
|
|
474
|
-
description: "
|
|
810
|
+
name: "git_pull",
|
|
811
|
+
description: "Download and merge changes from a remote repository into the current branch. Combines git fetch and git merge. Supports rebase mode to maintain linear history. Use to update your local branch with remote changes. Requires user approval before execution.",
|
|
475
812
|
tags: ["git", "pull"],
|
|
476
813
|
parameters,
|
|
477
814
|
validate: (args) => {
|
|
@@ -496,32 +833,26 @@ function createGitPullTool() {
|
|
|
496
833
|
const remote = typedArgs.remote || "origin";
|
|
497
834
|
const branch = typedArgs.branch || "current branch";
|
|
498
835
|
const rebase = typedArgs.rebase ? " (with rebase)" : "";
|
|
499
|
-
return `Pull${rebase} from ${remote}/${branch} in ${workingDir}
|
|
836
|
+
return `Pull${rebase} from ${remote}/${branch} in ${workingDir}?\n\nIMPORTANT: After getting user confirmation, you MUST call the execute_git_pull tool with these exact arguments: {"path": ${typedArgs.path ? `"${typedArgs.path}"` : "undefined"}, "remote": ${typedArgs.remote ? `"${typedArgs.remote}"` : "undefined"}, "branch": ${typedArgs.branch ? `"${typedArgs.branch}"` : "undefined"}, "rebase": ${typedArgs.rebase === true}}`;
|
|
500
837
|
}),
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
...(context.conversationId && { conversationId: context.conversationId }),
|
|
513
|
-
});
|
|
514
|
-
// For now, return a simple pull message
|
|
515
|
-
return {
|
|
516
|
-
success: true,
|
|
517
|
-
result: {
|
|
518
|
-
workingDirectory: workingDir,
|
|
519
|
-
remote: typedArgs.remote || "origin",
|
|
520
|
-
branch: typedArgs.branch || "current",
|
|
521
|
-
rebase: typedArgs.rebase || false,
|
|
522
|
-
message: "Changes would be pulled successfully",
|
|
838
|
+
errorMessage: "Approval required: Git pull requires user confirmation.",
|
|
839
|
+
execute: {
|
|
840
|
+
toolName: "execute_git_pull",
|
|
841
|
+
buildArgs: (args) => {
|
|
842
|
+
const typedArgs = args;
|
|
843
|
+
return {
|
|
844
|
+
path: typedArgs.path,
|
|
845
|
+
remote: typedArgs.remote,
|
|
846
|
+
branch: typedArgs.branch,
|
|
847
|
+
rebase: typedArgs.rebase,
|
|
848
|
+
};
|
|
523
849
|
},
|
|
524
|
-
}
|
|
850
|
+
},
|
|
851
|
+
},
|
|
852
|
+
handler: (_args, _context) => effect_1.Effect.succeed({
|
|
853
|
+
success: false,
|
|
854
|
+
result: null,
|
|
855
|
+
error: "Approval required",
|
|
525
856
|
}),
|
|
526
857
|
createSummary: (result) => {
|
|
527
858
|
if (result.success && typeof result.result === "object" && result.result !== null) {
|
|
@@ -545,8 +876,8 @@ function createGitCheckoutTool() {
|
|
|
545
876
|
})
|
|
546
877
|
.strict();
|
|
547
878
|
return (0, base_tool_1.defineTool)({
|
|
548
|
-
name: "
|
|
549
|
-
description: "Switch
|
|
879
|
+
name: "git_checkout",
|
|
880
|
+
description: "Switch to a different branch or create a new branch. Changes the working directory to match the specified branch. Can create new branches or force checkout (discarding local changes). Use to navigate between branches or start work on a new feature branch. Requires user approval before execution.",
|
|
550
881
|
tags: ["git", "checkout"],
|
|
551
882
|
parameters,
|
|
552
883
|
validate: (args) => {
|
|
@@ -570,22 +901,253 @@ function createGitCheckoutTool() {
|
|
|
570
901
|
});
|
|
571
902
|
const create = typedArgs.create ? " (create new branch)" : "";
|
|
572
903
|
const force = typedArgs.force ? " (force - discards changes)" : "";
|
|
573
|
-
return `Checkout branch "${typedArgs.branch}"${create}${force} in ${workingDir}
|
|
904
|
+
return `Checkout branch "${typedArgs.branch}"${create}${force} in ${workingDir}?\n\nIMPORTANT: After getting user confirmation, you MUST call the execute_git_checkout tool with these exact arguments: {"path": ${typedArgs.path ? `"${typedArgs.path}"` : "undefined"}, "branch": "${typedArgs.branch}", "create": ${typedArgs.create === true}, "force": ${typedArgs.force === true}}`;
|
|
574
905
|
}),
|
|
906
|
+
errorMessage: "Approval required: Git checkout requires user confirmation.",
|
|
907
|
+
execute: {
|
|
908
|
+
toolName: "execute_git_checkout",
|
|
909
|
+
buildArgs: (args) => {
|
|
910
|
+
const typedArgs = args;
|
|
911
|
+
return {
|
|
912
|
+
path: typedArgs.path,
|
|
913
|
+
branch: typedArgs.branch,
|
|
914
|
+
create: typedArgs.create,
|
|
915
|
+
force: typedArgs.force,
|
|
916
|
+
};
|
|
917
|
+
},
|
|
918
|
+
},
|
|
919
|
+
},
|
|
920
|
+
handler: (_args, _context) => effect_1.Effect.succeed({
|
|
921
|
+
success: false,
|
|
922
|
+
result: null,
|
|
923
|
+
error: "Approval required",
|
|
924
|
+
}),
|
|
925
|
+
createSummary: (result) => {
|
|
926
|
+
if (result.success && typeof result.result === "object" && result.result !== null) {
|
|
927
|
+
const gitResult = result.result;
|
|
928
|
+
return `Switched to ${gitResult.branch}${gitResult.created ? " (newly created)" : ""}`;
|
|
929
|
+
}
|
|
930
|
+
return result.success ? "Git checkout successful" : "Git checkout failed";
|
|
931
|
+
},
|
|
932
|
+
});
|
|
933
|
+
}
|
|
934
|
+
function createExecuteGitPushTool() {
|
|
935
|
+
const parameters = zod_1.z
|
|
936
|
+
.object({
|
|
937
|
+
path: zod_1.z
|
|
938
|
+
.string()
|
|
939
|
+
.optional()
|
|
940
|
+
.describe("Path to the Git repository (defaults to current working directory)"),
|
|
941
|
+
remote: zod_1.z.string().optional().describe("Remote repository name (defaults to 'origin')"),
|
|
942
|
+
branch: zod_1.z.string().optional().describe("Branch to push (defaults to current branch)"),
|
|
943
|
+
force: zod_1.z.boolean().optional().describe("Force push (overwrites remote history)"),
|
|
944
|
+
})
|
|
945
|
+
.strict();
|
|
946
|
+
return (0, base_tool_1.defineTool)({
|
|
947
|
+
name: "execute_git_push",
|
|
948
|
+
description: "Internal tool that performs the actual git push operation after user has approved the git_push request. Uploads local commits to the remote repository.",
|
|
949
|
+
hidden: true,
|
|
950
|
+
parameters,
|
|
951
|
+
validate: (args) => {
|
|
952
|
+
const result = parameters.safeParse(args);
|
|
953
|
+
return result.success
|
|
954
|
+
? { valid: true, value: result.data }
|
|
955
|
+
: { valid: false, errors: result.error.issues.map((i) => i.message) };
|
|
956
|
+
},
|
|
957
|
+
handler: (args, context) => effect_1.Effect.gen(function* () {
|
|
958
|
+
const shell = yield* shell_1.FileSystemContextServiceTag;
|
|
959
|
+
const typedArgs = args;
|
|
960
|
+
const workingDirResult = yield* resolveWorkingDirectory(shell, context, typedArgs.path).pipe(effect_1.Effect.catchAll((error) => effect_1.Effect.succeed({
|
|
961
|
+
success: false,
|
|
962
|
+
result: null,
|
|
963
|
+
error: error instanceof Error ? error.message : String(error),
|
|
964
|
+
})));
|
|
965
|
+
if (typeof workingDirResult === "object" &&
|
|
966
|
+
"success" in workingDirResult &&
|
|
967
|
+
!workingDirResult.success) {
|
|
968
|
+
return workingDirResult;
|
|
969
|
+
}
|
|
970
|
+
const workingDir = workingDirResult;
|
|
971
|
+
const remote = typedArgs.remote || "origin";
|
|
972
|
+
const branch = typedArgs.branch || "";
|
|
973
|
+
const pushArgs = ["push"];
|
|
974
|
+
if (typedArgs.force) {
|
|
975
|
+
pushArgs.push("--force");
|
|
976
|
+
}
|
|
977
|
+
if (branch) {
|
|
978
|
+
pushArgs.push(remote, branch);
|
|
979
|
+
}
|
|
980
|
+
else {
|
|
981
|
+
pushArgs.push(remote);
|
|
982
|
+
}
|
|
983
|
+
const commandResult = yield* runGitCommand({
|
|
984
|
+
args: pushArgs,
|
|
985
|
+
workingDirectory: workingDir,
|
|
986
|
+
});
|
|
987
|
+
if (commandResult.exitCode !== 0) {
|
|
988
|
+
return {
|
|
989
|
+
success: false,
|
|
990
|
+
result: null,
|
|
991
|
+
error: commandResult.stderr || `git push failed with exit code ${commandResult.exitCode}`,
|
|
992
|
+
};
|
|
993
|
+
}
|
|
994
|
+
return {
|
|
995
|
+
success: true,
|
|
996
|
+
result: {
|
|
997
|
+
workingDirectory: workingDir,
|
|
998
|
+
remote,
|
|
999
|
+
branch: branch || "current",
|
|
1000
|
+
force: typedArgs.force || false,
|
|
1001
|
+
message: "Changes pushed successfully",
|
|
1002
|
+
},
|
|
1003
|
+
};
|
|
1004
|
+
}),
|
|
1005
|
+
createSummary: (result) => {
|
|
1006
|
+
if (result.success && typeof result.result === "object" && result.result !== null) {
|
|
1007
|
+
const gitResult = result.result;
|
|
1008
|
+
return `Pushed to ${gitResult.remote}/${gitResult.branch}${gitResult.force ? " (force)" : ""}`;
|
|
1009
|
+
}
|
|
1010
|
+
return result.success ? "Git push successful" : "Git push failed";
|
|
1011
|
+
},
|
|
1012
|
+
});
|
|
1013
|
+
}
|
|
1014
|
+
function createExecuteGitPullTool() {
|
|
1015
|
+
const parameters = zod_1.z
|
|
1016
|
+
.object({
|
|
1017
|
+
path: zod_1.z
|
|
1018
|
+
.string()
|
|
1019
|
+
.optional()
|
|
1020
|
+
.describe("Path to the Git repository (defaults to current working directory)"),
|
|
1021
|
+
remote: zod_1.z.string().optional().describe("Remote repository name (defaults to 'origin')"),
|
|
1022
|
+
branch: zod_1.z.string().optional().describe("Branch to pull (defaults to current branch)"),
|
|
1023
|
+
rebase: zod_1.z.boolean().optional().describe("Use rebase instead of merge"),
|
|
1024
|
+
})
|
|
1025
|
+
.strict();
|
|
1026
|
+
return (0, base_tool_1.defineTool)({
|
|
1027
|
+
name: "execute_git_pull",
|
|
1028
|
+
description: "Internal tool that performs the actual git pull operation after user has approved the git_pull request. Downloads and merges changes from the remote repository.",
|
|
1029
|
+
hidden: true,
|
|
1030
|
+
parameters,
|
|
1031
|
+
validate: (args) => {
|
|
1032
|
+
const result = parameters.safeParse(args);
|
|
1033
|
+
return result.success
|
|
1034
|
+
? { valid: true, value: result.data }
|
|
1035
|
+
: { valid: false, errors: result.error.issues.map((i) => i.message) };
|
|
575
1036
|
},
|
|
576
1037
|
handler: (args, context) => effect_1.Effect.gen(function* () {
|
|
577
1038
|
const shell = yield* shell_1.FileSystemContextServiceTag;
|
|
578
1039
|
const typedArgs = args;
|
|
579
|
-
const
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
1040
|
+
const workingDirResult = yield* resolveWorkingDirectory(shell, context, typedArgs.path).pipe(effect_1.Effect.catchAll((error) => effect_1.Effect.succeed({
|
|
1041
|
+
success: false,
|
|
1042
|
+
result: null,
|
|
1043
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1044
|
+
})));
|
|
1045
|
+
if (typeof workingDirResult === "object" &&
|
|
1046
|
+
"success" in workingDirResult &&
|
|
1047
|
+
!workingDirResult.success) {
|
|
1048
|
+
return workingDirResult;
|
|
1049
|
+
}
|
|
1050
|
+
const workingDir = workingDirResult;
|
|
1051
|
+
const remote = typedArgs.remote || "origin";
|
|
1052
|
+
const branch = typedArgs.branch || "";
|
|
1053
|
+
const pullArgs = ["pull"];
|
|
1054
|
+
if (typedArgs.rebase) {
|
|
1055
|
+
pullArgs.push("--rebase");
|
|
1056
|
+
}
|
|
1057
|
+
if (branch) {
|
|
1058
|
+
pullArgs.push(remote, branch);
|
|
1059
|
+
}
|
|
1060
|
+
else {
|
|
1061
|
+
pullArgs.push(remote);
|
|
1062
|
+
}
|
|
1063
|
+
const commandResult = yield* runGitCommand({
|
|
1064
|
+
args: pullArgs,
|
|
1065
|
+
workingDirectory: workingDir,
|
|
1066
|
+
});
|
|
1067
|
+
if (commandResult.exitCode !== 0) {
|
|
1068
|
+
return {
|
|
1069
|
+
success: false,
|
|
1070
|
+
result: null,
|
|
1071
|
+
error: commandResult.stderr || `git pull failed with exit code ${commandResult.exitCode}`,
|
|
1072
|
+
};
|
|
1073
|
+
}
|
|
1074
|
+
return {
|
|
1075
|
+
success: true,
|
|
1076
|
+
result: {
|
|
1077
|
+
workingDirectory: workingDir,
|
|
1078
|
+
remote,
|
|
1079
|
+
branch: branch || "current",
|
|
1080
|
+
rebase: typedArgs.rebase || false,
|
|
1081
|
+
message: "Changes pulled successfully",
|
|
1082
|
+
},
|
|
1083
|
+
};
|
|
1084
|
+
}),
|
|
1085
|
+
createSummary: (result) => {
|
|
1086
|
+
if (result.success && typeof result.result === "object" && result.result !== null) {
|
|
1087
|
+
const gitResult = result.result;
|
|
1088
|
+
return `Pulled from ${gitResult.remote}/${gitResult.branch}${gitResult.rebase ? " (rebase)" : ""}`;
|
|
1089
|
+
}
|
|
1090
|
+
return result.success ? "Git pull successful" : "Git pull failed";
|
|
1091
|
+
},
|
|
1092
|
+
});
|
|
1093
|
+
}
|
|
1094
|
+
function createExecuteGitCheckoutTool() {
|
|
1095
|
+
const parameters = zod_1.z
|
|
1096
|
+
.object({
|
|
1097
|
+
path: zod_1.z
|
|
1098
|
+
.string()
|
|
1099
|
+
.optional()
|
|
1100
|
+
.describe("Path to the Git repository (defaults to current working directory)"),
|
|
1101
|
+
branch: zod_1.z.string().min(1).describe("Branch name to checkout"),
|
|
1102
|
+
create: zod_1.z.boolean().optional().describe("Create the branch if it doesn't exist"),
|
|
1103
|
+
force: zod_1.z.boolean().optional().describe("Force checkout (discards local changes)"),
|
|
1104
|
+
})
|
|
1105
|
+
.strict();
|
|
1106
|
+
return (0, base_tool_1.defineTool)({
|
|
1107
|
+
name: "execute_git_checkout",
|
|
1108
|
+
description: "Internal tool that performs the actual git checkout operation after user has approved the git_checkout request. Switches to the specified branch or creates a new branch.",
|
|
1109
|
+
hidden: true,
|
|
1110
|
+
parameters,
|
|
1111
|
+
validate: (args) => {
|
|
1112
|
+
const result = parameters.safeParse(args);
|
|
1113
|
+
return result.success
|
|
1114
|
+
? { valid: true, value: result.data }
|
|
1115
|
+
: { valid: false, errors: result.error.issues.map((i) => i.message) };
|
|
1116
|
+
},
|
|
1117
|
+
handler: (args, context) => effect_1.Effect.gen(function* () {
|
|
1118
|
+
const shell = yield* shell_1.FileSystemContextServiceTag;
|
|
1119
|
+
const typedArgs = args;
|
|
1120
|
+
const workingDirResult = yield* resolveWorkingDirectory(shell, context, typedArgs.path).pipe(effect_1.Effect.catchAll((error) => effect_1.Effect.succeed({
|
|
1121
|
+
success: false,
|
|
1122
|
+
result: null,
|
|
1123
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1124
|
+
})));
|
|
1125
|
+
if (typeof workingDirResult === "object" &&
|
|
1126
|
+
"success" in workingDirResult &&
|
|
1127
|
+
!workingDirResult.success) {
|
|
1128
|
+
return workingDirResult;
|
|
1129
|
+
}
|
|
1130
|
+
const workingDir = workingDirResult;
|
|
1131
|
+
const checkoutArgs = ["checkout"];
|
|
1132
|
+
if (typedArgs.create) {
|
|
1133
|
+
checkoutArgs.push("-b");
|
|
1134
|
+
}
|
|
1135
|
+
if (typedArgs.force) {
|
|
1136
|
+
checkoutArgs.push("--force");
|
|
1137
|
+
}
|
|
1138
|
+
checkoutArgs.push(typedArgs.branch);
|
|
1139
|
+
const commandResult = yield* runGitCommand({
|
|
1140
|
+
args: checkoutArgs,
|
|
1141
|
+
workingDirectory: workingDir,
|
|
1142
|
+
});
|
|
1143
|
+
if (commandResult.exitCode !== 0) {
|
|
1144
|
+
return {
|
|
1145
|
+
success: false,
|
|
1146
|
+
result: null,
|
|
1147
|
+
error: commandResult.stderr ||
|
|
1148
|
+
`git checkout failed with exit code ${commandResult.exitCode}`,
|
|
1149
|
+
};
|
|
1150
|
+
}
|
|
589
1151
|
return {
|
|
590
1152
|
success: true,
|
|
591
1153
|
result: {
|