openvibe 0.63.2 → 0.63.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +81 -0
- package/README.md +39 -0
- package/README_CN.md +1 -1
- package/dist/cli/args.d.ts +3 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +22 -2
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +5 -3
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/companion/executor/bash-executor.d.ts +30 -0
- package/dist/core/companion/executor/bash-executor.d.ts.map +1 -0
- package/dist/core/companion/executor/bash-executor.js +105 -0
- package/dist/core/companion/executor/bash-executor.js.map +1 -0
- package/dist/core/companion/executor/code-executor.d.ts +33 -0
- package/dist/core/companion/executor/code-executor.d.ts.map +1 -0
- package/dist/core/companion/executor/code-executor.js +144 -0
- package/dist/core/companion/executor/code-executor.js.map +1 -0
- package/dist/core/companion/executor/resource-monitor.d.ts +55 -0
- package/dist/core/companion/executor/resource-monitor.d.ts.map +1 -0
- package/dist/core/companion/executor/resource-monitor.js +141 -0
- package/dist/core/companion/executor/resource-monitor.js.map +1 -0
- package/dist/core/companion/http-server.d.ts +92 -0
- package/dist/core/companion/http-server.d.ts.map +1 -0
- package/dist/core/companion/http-server.js +229 -0
- package/dist/core/companion/http-server.js.map +1 -0
- package/dist/core/companion/index.d.ts +29 -0
- package/dist/core/companion/index.d.ts.map +1 -0
- package/dist/core/companion/index.js +48 -0
- package/dist/core/companion/index.js.map +1 -0
- package/dist/core/companion/scheduler/resource-scheduler.d.ts +82 -0
- package/dist/core/companion/scheduler/resource-scheduler.d.ts.map +1 -0
- package/dist/core/companion/scheduler/resource-scheduler.js +333 -0
- package/dist/core/companion/scheduler/resource-scheduler.js.map +1 -0
- package/dist/core/companion/scheduler/workers/base-worker.d.ts +87 -0
- package/dist/core/companion/scheduler/workers/base-worker.d.ts.map +1 -0
- package/dist/core/companion/scheduler/workers/base-worker.js +70 -0
- package/dist/core/companion/scheduler/workers/base-worker.js.map +1 -0
- package/dist/core/companion/scheduler/workers/cpu-worker.d.ts +12 -0
- package/dist/core/companion/scheduler/workers/cpu-worker.d.ts.map +1 -0
- package/dist/core/companion/scheduler/workers/cpu-worker.js +134 -0
- package/dist/core/companion/scheduler/workers/cpu-worker.js.map +1 -0
- package/dist/core/companion/scheduler/workers/gpu-worker.d.ts +16 -0
- package/dist/core/companion/scheduler/workers/gpu-worker.d.ts.map +1 -0
- package/dist/core/companion/scheduler/workers/gpu-worker.js +167 -0
- package/dist/core/companion/scheduler/workers/gpu-worker.js.map +1 -0
- package/dist/core/companion/scheduler/workers/index.d.ts +6 -0
- package/dist/core/companion/scheduler/workers/index.d.ts.map +1 -0
- package/dist/core/companion/scheduler/workers/index.js +6 -0
- package/dist/core/companion/scheduler/workers/index.js.map +1 -0
- package/dist/core/companion/scheduler/workers/io-worker.d.ts +17 -0
- package/dist/core/companion/scheduler/workers/io-worker.d.ts.map +1 -0
- package/dist/core/companion/scheduler/workers/io-worker.js +197 -0
- package/dist/core/companion/scheduler/workers/io-worker.js.map +1 -0
- package/dist/core/companion/scheduler/workers/network-worker.d.ts +13 -0
- package/dist/core/companion/scheduler/workers/network-worker.d.ts.map +1 -0
- package/dist/core/companion/scheduler/workers/network-worker.js +167 -0
- package/dist/core/companion/scheduler/workers/network-worker.js.map +1 -0
- package/dist/core/companion/security/security-manager.d.ts +50 -0
- package/dist/core/companion/security/security-manager.d.ts.map +1 -0
- package/dist/core/companion/security/security-manager.js +102 -0
- package/dist/core/companion/security/security-manager.js.map +1 -0
- package/dist/core/hybrid-cloud/extension.d.ts +8 -0
- package/dist/core/hybrid-cloud/extension.d.ts.map +1 -0
- package/dist/core/hybrid-cloud/extension.js +64 -0
- package/dist/core/hybrid-cloud/extension.js.map +1 -0
- package/dist/core/hybrid-cloud/index.d.ts +98 -0
- package/dist/core/hybrid-cloud/index.d.ts.map +1 -0
- package/dist/core/hybrid-cloud/index.js +211 -0
- package/dist/core/hybrid-cloud/index.js.map +1 -0
- package/dist/core/keybindings.d.ts +1 -1
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +3 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +6 -1
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +13 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +35 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +7 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +46 -0
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/todo-manager.d.ts +32 -0
- package/dist/core/todo-manager.d.ts.map +1 -0
- package/dist/core/todo-manager.js +117 -0
- package/dist/core/todo-manager.js.map +1 -0
- package/dist/core/tools/batch-write.d.ts +42 -0
- package/dist/core/tools/batch-write.d.ts.map +1 -0
- package/dist/core/tools/batch-write.js +267 -0
- package/dist/core/tools/batch-write.js.map +1 -0
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +10 -2
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/fast-executor.d.ts +6 -1
- package/dist/core/tools/fast-executor.d.ts.map +1 -1
- package/dist/core/tools/fast-executor.js +83 -4
- package/dist/core/tools/fast-executor.js.map +1 -1
- package/dist/core/tools/index.d.ts +141 -0
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +30 -0
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/todo.d.ts +47 -0
- package/dist/core/tools/todo.d.ts.map +1 -0
- package/dist/core/tools/todo.js +212 -0
- package/dist/core/tools/todo.js.map +1 -0
- package/dist/core/tools/unified.d.ts +121 -0
- package/dist/core/tools/unified.d.ts.map +1 -0
- package/dist/core/tools/unified.js +481 -0
- package/dist/core/tools/unified.js.map +1 -0
- package/dist/core/tools/write.d.ts +1 -1
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +20 -5
- package/dist/core/tools/write.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +63 -1
- package/dist/main.js.map +1 -1
- package/dist/modes/index.d.ts +2 -0
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/index.js +2 -0
- package/dist/modes/index.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +1 -0
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +1 -0
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/todo-display.d.ts +9 -0
- package/dist/modes/interactive/components/todo-display.d.ts.map +1 -0
- package/dist/modes/interactive/components/todo-display.js +60 -0
- package/dist/modes/interactive/components/todo-display.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +8 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +151 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/plan-mode.d.ts +14 -0
- package/dist/modes/plan-mode.d.ts.map +1 -0
- package/dist/modes/plan-mode.js +107 -0
- package/dist/modes/plan-mode.js.map +1 -0
- package/dist/modes/spec-mode.d.ts +16 -0
- package/dist/modes/spec-mode.d.ts.map +1 -0
- package/dist/modes/spec-mode.js +186 -0
- package/dist/modes/spec-mode.js.map +1 -0
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +2 -2
- package/dist/utils/version-check.js.map +1 -1
- package/docs/HYBRID_CLOUD_README.md +188 -0
- package/docs/hybrid-architecture-design.md +317 -0
- package/docs/todo.md +71 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/custom-provider-qwen-cli/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
import { Type } from "@sinclair/typebox";
|
|
2
|
+
import { spawn } from "child_process";
|
|
3
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, unlinkSync, writeFileSync } from "fs";
|
|
4
|
+
import { homedir } from "os";
|
|
5
|
+
import { basename, dirname, isAbsolute, join, relative, resolve } from "path";
|
|
6
|
+
import { getShellConfig, getShellEnv, killProcessTree } from "../../utils/shell.js";
|
|
7
|
+
const ReadOperation = Type.Object({
|
|
8
|
+
operation: Type.Literal("read"),
|
|
9
|
+
path: Type.String({ description: "File path to read" }),
|
|
10
|
+
offset: Type.Optional(Type.Number({ description: "Start line number" })),
|
|
11
|
+
limit: Type.Optional(Type.Number({ description: "Number of lines to read" })),
|
|
12
|
+
});
|
|
13
|
+
const WriteOperation = Type.Object({
|
|
14
|
+
operation: Type.Literal("write"),
|
|
15
|
+
path: Type.String({ description: "File path to write" }),
|
|
16
|
+
content: Type.String({ description: "Content to write" }),
|
|
17
|
+
createDirs: Type.Optional(Type.Boolean({ description: "Create parent directories", default: true })),
|
|
18
|
+
});
|
|
19
|
+
const EditOperation = Type.Object({
|
|
20
|
+
operation: Type.Literal("edit"),
|
|
21
|
+
path: Type.String({ description: "File path to edit" }),
|
|
22
|
+
oldText: Type.String({ description: "Text to find and replace" }),
|
|
23
|
+
newText: Type.String({ description: "New text" }),
|
|
24
|
+
replaceAll: Type.Optional(Type.Boolean({ description: "Replace all occurrences" })),
|
|
25
|
+
});
|
|
26
|
+
const BashOperation = Type.Object({
|
|
27
|
+
operation: Type.Literal("bash"),
|
|
28
|
+
command: Type.String({ description: "Bash command to execute" }),
|
|
29
|
+
timeout: Type.Optional(Type.Number({ description: "Timeout in seconds" })),
|
|
30
|
+
cwd: Type.Optional(Type.String({ description: "Working directory" })),
|
|
31
|
+
});
|
|
32
|
+
const GrepOperation = Type.Object({
|
|
33
|
+
operation: Type.Literal("grep"),
|
|
34
|
+
pattern: Type.String({ description: "Pattern to search" }),
|
|
35
|
+
path: Type.Optional(Type.String({ description: "Directory or file to search" })),
|
|
36
|
+
type: Type.Optional(Type.String({ description: "File type filter" })),
|
|
37
|
+
glob: Type.Optional(Type.String({ description: "Glob pattern" })),
|
|
38
|
+
i: Type.Optional(Type.Boolean({ description: "Case insensitive" })),
|
|
39
|
+
head_limit: Type.Optional(Type.Number({ description: "Max results" })),
|
|
40
|
+
});
|
|
41
|
+
const FindOperation = Type.Object({
|
|
42
|
+
operation: Type.Literal("find"),
|
|
43
|
+
pattern: Type.String({ description: "File name pattern" }),
|
|
44
|
+
path: Type.Optional(Type.String({ description: "Directory to search" })),
|
|
45
|
+
type: Type.Optional(Type.String({ description: "File type: f, d, l" })),
|
|
46
|
+
});
|
|
47
|
+
const LsOperation = Type.Object({
|
|
48
|
+
operation: Type.Literal("ls"),
|
|
49
|
+
path: Type.Optional(Type.String({ description: "Directory to list" })),
|
|
50
|
+
});
|
|
51
|
+
const BatchWriteOperation = Type.Object({
|
|
52
|
+
operation: Type.Literal("batch_write"),
|
|
53
|
+
files: Type.Array(Type.Object({
|
|
54
|
+
path: Type.String(),
|
|
55
|
+
content: Type.String(),
|
|
56
|
+
})),
|
|
57
|
+
atomic: Type.Optional(Type.Boolean({ default: true })),
|
|
58
|
+
backup: Type.Optional(Type.Boolean({ default: true })),
|
|
59
|
+
});
|
|
60
|
+
const UnifiedSchema = Type.Object({
|
|
61
|
+
operations: Type.Array(Type.Union([
|
|
62
|
+
ReadOperation,
|
|
63
|
+
WriteOperation,
|
|
64
|
+
EditOperation,
|
|
65
|
+
BashOperation,
|
|
66
|
+
GrepOperation,
|
|
67
|
+
FindOperation,
|
|
68
|
+
LsOperation,
|
|
69
|
+
BatchWriteOperation,
|
|
70
|
+
]), { description: "Operations to execute" }),
|
|
71
|
+
parallel: Type.Optional(Type.Boolean({ description: "Execute operations in parallel", default: false })),
|
|
72
|
+
});
|
|
73
|
+
export { UnifiedSchema };
|
|
74
|
+
function resolvePath(path, cwd) {
|
|
75
|
+
if (isAbsolute(path))
|
|
76
|
+
return path;
|
|
77
|
+
if (path.startsWith("~"))
|
|
78
|
+
return join(homedir(), path.slice(1));
|
|
79
|
+
return resolve(cwd, path);
|
|
80
|
+
}
|
|
81
|
+
function getBackupDir() {
|
|
82
|
+
const backupBase = resolve(homedir(), ".openvibe", "backups");
|
|
83
|
+
if (!existsSync(backupBase)) {
|
|
84
|
+
mkdirSync(backupBase, { recursive: true });
|
|
85
|
+
}
|
|
86
|
+
return backupBase;
|
|
87
|
+
}
|
|
88
|
+
function createBackup(filePath) {
|
|
89
|
+
if (!existsSync(filePath))
|
|
90
|
+
return null;
|
|
91
|
+
const backupDir = getBackupDir();
|
|
92
|
+
const timestamp = Date.now();
|
|
93
|
+
const fileName = basename(filePath);
|
|
94
|
+
const backupPath = resolve(backupDir, `${fileName}.${timestamp}.bak`);
|
|
95
|
+
try {
|
|
96
|
+
writeFileSync(backupPath, readFileSync(filePath));
|
|
97
|
+
return backupPath;
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async function executeRead(input, cwd) {
|
|
104
|
+
const startTime = Date.now();
|
|
105
|
+
try {
|
|
106
|
+
const absolutePath = resolvePath(input.path, cwd);
|
|
107
|
+
if (!existsSync(absolutePath)) {
|
|
108
|
+
return { operation: "read", success: false, error: `File not found: ${input.path}`, path: absolutePath };
|
|
109
|
+
}
|
|
110
|
+
const content = readFileSync(absolutePath, "utf-8");
|
|
111
|
+
const lines = content.split("\n");
|
|
112
|
+
const offset = input.offset ?? 0;
|
|
113
|
+
const limit = input.limit ?? 2000;
|
|
114
|
+
const selectedLines = lines.slice(offset, offset + limit);
|
|
115
|
+
const output = selectedLines.join("\n");
|
|
116
|
+
return {
|
|
117
|
+
operation: "read",
|
|
118
|
+
success: true,
|
|
119
|
+
output: `${input.path}:\n${output}`,
|
|
120
|
+
path: absolutePath,
|
|
121
|
+
duration: Date.now() - startTime,
|
|
122
|
+
bytes: Buffer.byteLength(content),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
catch (e) {
|
|
126
|
+
return { operation: "read", success: false, error: e instanceof Error ? e.message : String(e) };
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async function executeWrite(input, cwd, onUpdate) {
|
|
130
|
+
const startTime = Date.now();
|
|
131
|
+
try {
|
|
132
|
+
const absolutePath = resolvePath(input.path, cwd);
|
|
133
|
+
const parentDir = dirname(absolutePath);
|
|
134
|
+
if (!existsSync(parentDir) && (input.createDirs ?? true)) {
|
|
135
|
+
mkdirSync(parentDir, { recursive: true });
|
|
136
|
+
}
|
|
137
|
+
const fileExists = existsSync(absolutePath);
|
|
138
|
+
let backupPath = null;
|
|
139
|
+
if (fileExists) {
|
|
140
|
+
backupPath = createBackup(absolutePath);
|
|
141
|
+
}
|
|
142
|
+
writeFileSync(absolutePath, input.content, "utf-8");
|
|
143
|
+
const bytes = Buffer.byteLength(input.content);
|
|
144
|
+
if (backupPath && existsSync(backupPath)) {
|
|
145
|
+
unlinkSync(backupPath);
|
|
146
|
+
}
|
|
147
|
+
const status = fileExists ? "updated" : "created";
|
|
148
|
+
onUpdate?.({
|
|
149
|
+
content: [{ type: "text", text: `[${status === "created" ? "+" : "~"}] ${input.path} (${bytes} bytes)` }],
|
|
150
|
+
details: { success: true, total: 1, succeeded: 1, failed: 0, results: [], duration: 0 },
|
|
151
|
+
});
|
|
152
|
+
return {
|
|
153
|
+
operation: "write",
|
|
154
|
+
success: true,
|
|
155
|
+
output: `Wrote ${bytes} bytes to ${input.path}`,
|
|
156
|
+
path: absolutePath,
|
|
157
|
+
duration: Date.now() - startTime,
|
|
158
|
+
bytes,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
catch (e) {
|
|
162
|
+
return { operation: "write", success: false, error: e instanceof Error ? e.message : String(e) };
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
async function executeEdit(input, cwd, onUpdate) {
|
|
166
|
+
const startTime = Date.now();
|
|
167
|
+
try {
|
|
168
|
+
const absolutePath = resolvePath(input.path, cwd);
|
|
169
|
+
if (!existsSync(absolutePath)) {
|
|
170
|
+
return { operation: "edit", success: false, error: `File not found: ${input.path}`, path: absolutePath };
|
|
171
|
+
}
|
|
172
|
+
const content = readFileSync(absolutePath, "utf-8");
|
|
173
|
+
let newContent;
|
|
174
|
+
let replacements = 0;
|
|
175
|
+
if (input.replaceAll) {
|
|
176
|
+
const parts = content.split(input.oldText);
|
|
177
|
+
replacements = parts.length - 1;
|
|
178
|
+
newContent = parts.join(input.newText);
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
const index = content.indexOf(input.oldText);
|
|
182
|
+
if (index === -1) {
|
|
183
|
+
return { operation: "edit", success: false, error: `Text not found in ${input.path}` };
|
|
184
|
+
}
|
|
185
|
+
newContent = content.slice(0, index) + input.newText + content.slice(index + input.oldText.length);
|
|
186
|
+
replacements = 1;
|
|
187
|
+
}
|
|
188
|
+
const backupPath = createBackup(absolutePath);
|
|
189
|
+
writeFileSync(absolutePath, newContent, "utf-8");
|
|
190
|
+
if (backupPath && existsSync(backupPath)) {
|
|
191
|
+
unlinkSync(backupPath);
|
|
192
|
+
}
|
|
193
|
+
onUpdate?.({
|
|
194
|
+
content: [
|
|
195
|
+
{ type: "text", text: `[~] ${input.path} (${replacements} replacement${replacements > 1 ? "s" : ""})` },
|
|
196
|
+
],
|
|
197
|
+
details: { success: true, total: 1, succeeded: 1, failed: 0, results: [], duration: 0 },
|
|
198
|
+
});
|
|
199
|
+
return {
|
|
200
|
+
operation: "edit",
|
|
201
|
+
success: true,
|
|
202
|
+
output: `Replaced ${replacements} occurrence(s) in ${input.path}`,
|
|
203
|
+
path: absolutePath,
|
|
204
|
+
duration: Date.now() - startTime,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
catch (e) {
|
|
208
|
+
return { operation: "edit", success: false, error: e instanceof Error ? e.message : String(e) };
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
async function executeBash(input, cwd, signal, onUpdate) {
|
|
212
|
+
const startTime = Date.now();
|
|
213
|
+
const workDir = input.cwd ? resolvePath(input.cwd, cwd) : cwd;
|
|
214
|
+
return new Promise((resolveResult) => {
|
|
215
|
+
const { shell, args } = getShellConfig();
|
|
216
|
+
const stdout = [];
|
|
217
|
+
const stderr = [];
|
|
218
|
+
const child = spawn(shell, [...args, input.command], {
|
|
219
|
+
cwd: workDir,
|
|
220
|
+
detached: true,
|
|
221
|
+
env: getShellEnv(),
|
|
222
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
223
|
+
});
|
|
224
|
+
let timedOut = false;
|
|
225
|
+
const timeoutMs = (input.timeout ?? 120) * 1000;
|
|
226
|
+
const timeoutHandle = setTimeout(() => {
|
|
227
|
+
timedOut = true;
|
|
228
|
+
if (child.pid)
|
|
229
|
+
killProcessTree(child.pid);
|
|
230
|
+
}, timeoutMs);
|
|
231
|
+
const onAbort = () => {
|
|
232
|
+
if (child.pid)
|
|
233
|
+
killProcessTree(child.pid);
|
|
234
|
+
};
|
|
235
|
+
signal?.addEventListener("abort", onAbort);
|
|
236
|
+
child.stdout?.on("data", (data) => {
|
|
237
|
+
stdout.push(data);
|
|
238
|
+
onUpdate?.({
|
|
239
|
+
content: [{ type: "text", text: data.toString() }],
|
|
240
|
+
details: { success: true, total: 1, succeeded: 0, failed: 0, results: [], duration: 0 },
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
child.stderr?.on("data", (data) => stderr.push(data));
|
|
244
|
+
child.on("close", (code) => {
|
|
245
|
+
clearTimeout(timeoutHandle);
|
|
246
|
+
signal?.removeEventListener("abort", onAbort);
|
|
247
|
+
const stdoutText = Buffer.concat(stdout).toString();
|
|
248
|
+
const stderrText = Buffer.concat(stderr).toString();
|
|
249
|
+
const output = stdoutText + (stderrText ? `\nstderr:\n${stderrText}` : "");
|
|
250
|
+
resolveResult({
|
|
251
|
+
operation: "bash",
|
|
252
|
+
success: code === 0 && !timedOut,
|
|
253
|
+
output: timedOut ? `Command timed out after ${input.timeout}s\n${output}` : output,
|
|
254
|
+
error: code !== 0 ? `Exit code: ${code}` : undefined,
|
|
255
|
+
duration: Date.now() - startTime,
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
child.on("error", (err) => {
|
|
259
|
+
clearTimeout(timeoutHandle);
|
|
260
|
+
signal?.removeEventListener("abort", onAbort);
|
|
261
|
+
resolveResult({
|
|
262
|
+
operation: "bash",
|
|
263
|
+
success: false,
|
|
264
|
+
error: err.message,
|
|
265
|
+
duration: Date.now() - startTime,
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
async function executeGrep(input, cwd) {
|
|
271
|
+
const startTime = Date.now();
|
|
272
|
+
try {
|
|
273
|
+
const searchPath = input.path ? resolvePath(input.path, cwd) : cwd;
|
|
274
|
+
const pattern = input.i ? new RegExp(input.pattern, "gi") : new RegExp(input.pattern, "g");
|
|
275
|
+
const results = [];
|
|
276
|
+
let count = 0;
|
|
277
|
+
const maxResults = input.head_limit ?? 100;
|
|
278
|
+
const searchFile = (filePath) => {
|
|
279
|
+
if (count >= maxResults)
|
|
280
|
+
return;
|
|
281
|
+
try {
|
|
282
|
+
const content = readFileSync(filePath, "utf-8");
|
|
283
|
+
const lines = content.split("\n");
|
|
284
|
+
for (let i = 0; i < lines.length && count < maxResults; i++) {
|
|
285
|
+
if (pattern.test(lines[i])) {
|
|
286
|
+
results.push(`${filePath}:${i + 1}:${lines[i].trim()}`);
|
|
287
|
+
count++;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
catch { }
|
|
292
|
+
};
|
|
293
|
+
const searchDir = (dir) => {
|
|
294
|
+
try {
|
|
295
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
296
|
+
for (const entry of entries) {
|
|
297
|
+
if (count >= maxResults)
|
|
298
|
+
break;
|
|
299
|
+
const fullPath = join(dir, entry.name);
|
|
300
|
+
if (entry.isDirectory()) {
|
|
301
|
+
searchDir(fullPath);
|
|
302
|
+
}
|
|
303
|
+
else if (entry.isFile()) {
|
|
304
|
+
searchFile(fullPath);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
catch { }
|
|
309
|
+
};
|
|
310
|
+
if (existsSync(searchPath)) {
|
|
311
|
+
const stat = statSync(searchPath);
|
|
312
|
+
if (stat.isDirectory()) {
|
|
313
|
+
searchDir(searchPath);
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
searchFile(searchPath);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return {
|
|
320
|
+
operation: "grep",
|
|
321
|
+
success: true,
|
|
322
|
+
output: results.length > 0 ? results.join("\n") : "No matches found",
|
|
323
|
+
duration: Date.now() - startTime,
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
catch (e) {
|
|
327
|
+
return { operation: "grep", success: false, error: e instanceof Error ? e.message : String(e) };
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
async function executeFind(input, cwd) {
|
|
331
|
+
const startTime = Date.now();
|
|
332
|
+
try {
|
|
333
|
+
const searchPath = input.path ? resolvePath(input.path, cwd) : cwd;
|
|
334
|
+
const results = [];
|
|
335
|
+
const pattern = new RegExp(input.pattern.replace(/\*/g, ".*"));
|
|
336
|
+
const searchDir = (dir) => {
|
|
337
|
+
try {
|
|
338
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
339
|
+
for (const entry of entries) {
|
|
340
|
+
const fullPath = join(dir, entry.name);
|
|
341
|
+
if (pattern.test(entry.name)) {
|
|
342
|
+
results.push(relative(searchPath, fullPath));
|
|
343
|
+
}
|
|
344
|
+
if (entry.isDirectory() && !entry.name.startsWith(".")) {
|
|
345
|
+
searchDir(fullPath);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
catch { }
|
|
350
|
+
};
|
|
351
|
+
searchDir(searchPath);
|
|
352
|
+
return {
|
|
353
|
+
operation: "find",
|
|
354
|
+
success: true,
|
|
355
|
+
output: results.length > 0 ? results.join("\n") : "No files found",
|
|
356
|
+
duration: Date.now() - startTime,
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
catch (e) {
|
|
360
|
+
return { operation: "find", success: false, error: e instanceof Error ? e.message : String(e) };
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
async function executeLs(input, cwd) {
|
|
364
|
+
const startTime = Date.now();
|
|
365
|
+
try {
|
|
366
|
+
const listPath = input.path ? resolvePath(input.path, cwd) : cwd;
|
|
367
|
+
const entries = readdirSync(listPath, { withFileTypes: true });
|
|
368
|
+
const output = entries
|
|
369
|
+
.map((e) => `${e.isDirectory() ? "d" : "-"} ${e.name}`)
|
|
370
|
+
.sort()
|
|
371
|
+
.join("\n");
|
|
372
|
+
return {
|
|
373
|
+
operation: "ls",
|
|
374
|
+
success: true,
|
|
375
|
+
output: `${input.path || "."}:\n${output}`,
|
|
376
|
+
path: listPath,
|
|
377
|
+
duration: Date.now() - startTime,
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
catch (e) {
|
|
381
|
+
return { operation: "ls", success: false, error: e instanceof Error ? e.message : String(e) };
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
async function executeBatchWrite(input, cwd, onUpdate) {
|
|
385
|
+
const startTime = Date.now();
|
|
386
|
+
const results = [];
|
|
387
|
+
let succeeded = 0;
|
|
388
|
+
let failed = 0;
|
|
389
|
+
for (const file of input.files) {
|
|
390
|
+
const result = await executeWrite({ operation: "write", path: file.path, content: file.content }, cwd, onUpdate);
|
|
391
|
+
results.push(result);
|
|
392
|
+
if (result.success)
|
|
393
|
+
succeeded++;
|
|
394
|
+
else
|
|
395
|
+
failed++;
|
|
396
|
+
}
|
|
397
|
+
return {
|
|
398
|
+
operation: "batch_write",
|
|
399
|
+
success: failed === 0,
|
|
400
|
+
output: `Wrote ${succeeded}/${input.files.length} files`,
|
|
401
|
+
error: failed > 0 ? `${failed} files failed` : undefined,
|
|
402
|
+
duration: Date.now() - startTime,
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
export function createUnifiedTool(cwd) {
|
|
406
|
+
return {
|
|
407
|
+
name: "execute",
|
|
408
|
+
label: "execute",
|
|
409
|
+
description: "Unified tool for all file and shell operations. Supports read, write, edit, bash, grep, find, ls, and batch_write operations. Multiple operations can be executed in sequence or parallel.",
|
|
410
|
+
parameters: UnifiedSchema,
|
|
411
|
+
execute: async (_id, input, signal, onUpdate) => {
|
|
412
|
+
const startTime = Date.now();
|
|
413
|
+
const results = [];
|
|
414
|
+
let succeeded = 0;
|
|
415
|
+
let failed = 0;
|
|
416
|
+
const executeOperation = async (op) => {
|
|
417
|
+
switch (op.operation) {
|
|
418
|
+
case "read":
|
|
419
|
+
return executeRead(op, cwd);
|
|
420
|
+
case "write":
|
|
421
|
+
return executeWrite(op, cwd, onUpdate);
|
|
422
|
+
case "edit":
|
|
423
|
+
return executeEdit(op, cwd, onUpdate);
|
|
424
|
+
case "bash":
|
|
425
|
+
return executeBash(op, cwd, signal, onUpdate);
|
|
426
|
+
case "grep":
|
|
427
|
+
return executeGrep(op, cwd);
|
|
428
|
+
case "find":
|
|
429
|
+
return executeFind(op, cwd);
|
|
430
|
+
case "ls":
|
|
431
|
+
return executeLs(op, cwd);
|
|
432
|
+
case "batch_write":
|
|
433
|
+
return executeBatchWrite(op, cwd, onUpdate);
|
|
434
|
+
default:
|
|
435
|
+
return { operation: "unknown", success: false, error: "Unknown operation" };
|
|
436
|
+
}
|
|
437
|
+
};
|
|
438
|
+
if (input.parallel) {
|
|
439
|
+
const promises = input.operations.map(executeOperation);
|
|
440
|
+
const parallelResults = await Promise.all(promises);
|
|
441
|
+
results.push(...parallelResults);
|
|
442
|
+
}
|
|
443
|
+
else {
|
|
444
|
+
for (const op of input.operations) {
|
|
445
|
+
const result = await executeOperation(op);
|
|
446
|
+
results.push(result);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
succeeded = results.filter((r) => r.success).length;
|
|
450
|
+
failed = results.filter((r) => !r.success).length;
|
|
451
|
+
const duration = Date.now() - startTime;
|
|
452
|
+
const outputLines = [
|
|
453
|
+
`Execute Report`,
|
|
454
|
+
`==============`,
|
|
455
|
+
`Total: ${results.length} | Success: ${succeeded} | Failed: ${failed}`,
|
|
456
|
+
`Duration: ${duration}ms`,
|
|
457
|
+
"",
|
|
458
|
+
"Results:",
|
|
459
|
+
];
|
|
460
|
+
for (const r of results) {
|
|
461
|
+
const icon = r.success ? "+" : "x";
|
|
462
|
+
const info = r.output ? `: ${r.output.slice(0, 100)}${r.output.length > 100 ? "..." : ""}` : "";
|
|
463
|
+
const error = r.error ? ` - ${r.error}` : "";
|
|
464
|
+
outputLines.push(` [${icon}] ${r.operation}${info}${error}`);
|
|
465
|
+
}
|
|
466
|
+
return {
|
|
467
|
+
content: [{ type: "text", text: outputLines.join("\n") }],
|
|
468
|
+
details: {
|
|
469
|
+
success: failed === 0,
|
|
470
|
+
total: results.length,
|
|
471
|
+
succeeded,
|
|
472
|
+
failed,
|
|
473
|
+
results,
|
|
474
|
+
duration,
|
|
475
|
+
},
|
|
476
|
+
};
|
|
477
|
+
},
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
export const unifiedTool = createUnifiedTool(process.cwd());
|
|
481
|
+
//# sourceMappingURL=unified.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unified.js","sourceRoot":"","sources":["../../../src/core/tools/unified.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentTool, AgentToolUpdateCallback } from \"@boxiaolanya2008/pi-agent-core\";\nimport { type Static, Type } from \"@sinclair/typebox\";\nimport { spawn } from \"child_process\";\nimport { existsSync, mkdirSync, readdirSync, readFileSync, statSync, unlinkSync, writeFileSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { basename, dirname, isAbsolute, join, relative, resolve } from \"path\";\nimport { getShellConfig, getShellEnv, killProcessTree } from \"../../utils/shell.js\";\n\nconst ReadOperation = Type.Object({\n\toperation: Type.Literal(\"read\"),\n\tpath: Type.String({ description: \"File path to read\" }),\n\toffset: Type.Optional(Type.Number({ description: \"Start line number\" })),\n\tlimit: Type.Optional(Type.Number({ description: \"Number of lines to read\" })),\n});\n\nconst WriteOperation = Type.Object({\n\toperation: Type.Literal(\"write\"),\n\tpath: Type.String({ description: \"File path to write\" }),\n\tcontent: Type.String({ description: \"Content to write\" }),\n\tcreateDirs: Type.Optional(Type.Boolean({ description: \"Create parent directories\", default: true })),\n});\n\nconst EditOperation = Type.Object({\n\toperation: Type.Literal(\"edit\"),\n\tpath: Type.String({ description: \"File path to edit\" }),\n\toldText: Type.String({ description: \"Text to find and replace\" }),\n\tnewText: Type.String({ description: \"New text\" }),\n\treplaceAll: Type.Optional(Type.Boolean({ description: \"Replace all occurrences\" })),\n});\n\nconst BashOperation = Type.Object({\n\toperation: Type.Literal(\"bash\"),\n\tcommand: Type.String({ description: \"Bash command to execute\" }),\n\ttimeout: Type.Optional(Type.Number({ description: \"Timeout in seconds\" })),\n\tcwd: Type.Optional(Type.String({ description: \"Working directory\" })),\n});\n\nconst GrepOperation = Type.Object({\n\toperation: Type.Literal(\"grep\"),\n\tpattern: Type.String({ description: \"Pattern to search\" }),\n\tpath: Type.Optional(Type.String({ description: \"Directory or file to search\" })),\n\ttype: Type.Optional(Type.String({ description: \"File type filter\" })),\n\tglob: Type.Optional(Type.String({ description: \"Glob pattern\" })),\n\ti: Type.Optional(Type.Boolean({ description: \"Case insensitive\" })),\n\thead_limit: Type.Optional(Type.Number({ description: \"Max results\" })),\n});\n\nconst FindOperation = Type.Object({\n\toperation: Type.Literal(\"find\"),\n\tpattern: Type.String({ description: \"File name pattern\" }),\n\tpath: Type.Optional(Type.String({ description: \"Directory to search\" })),\n\ttype: Type.Optional(Type.String({ description: \"File type: f, d, l\" })),\n});\n\nconst LsOperation = Type.Object({\n\toperation: Type.Literal(\"ls\"),\n\tpath: Type.Optional(Type.String({ description: \"Directory to list\" })),\n});\n\nconst BatchWriteOperation = Type.Object({\n\toperation: Type.Literal(\"batch_write\"),\n\tfiles: Type.Array(\n\t\tType.Object({\n\t\t\tpath: Type.String(),\n\t\t\tcontent: Type.String(),\n\t\t}),\n\t),\n\tatomic: Type.Optional(Type.Boolean({ default: true })),\n\tbackup: Type.Optional(Type.Boolean({ default: true })),\n});\n\nconst UnifiedSchema = Type.Object({\n\toperations: Type.Array(\n\t\tType.Union([\n\t\t\tReadOperation,\n\t\t\tWriteOperation,\n\t\t\tEditOperation,\n\t\t\tBashOperation,\n\t\t\tGrepOperation,\n\t\t\tFindOperation,\n\t\t\tLsOperation,\n\t\t\tBatchWriteOperation,\n\t\t]),\n\t\t{ description: \"Operations to execute\" },\n\t),\n\tparallel: Type.Optional(Type.Boolean({ description: \"Execute operations in parallel\", default: false })),\n});\n\nexport type UnifiedInput = Static<typeof UnifiedSchema>;\nexport { UnifiedSchema };\n\ninterface OpResult {\n\toperation: string;\n\tsuccess: boolean;\n\toutput?: string;\n\terror?: string;\n\tpath?: string;\n\tduration?: number;\n\tbytes?: number;\n}\n\nexport interface UnifiedResult {\n\tsuccess: boolean;\n\ttotal: number;\n\tsucceeded: number;\n\tfailed: number;\n\tresults: OpResult[];\n\tduration: number;\n}\n\nfunction resolvePath(path: string, cwd: string): string {\n\tif (isAbsolute(path)) return path;\n\tif (path.startsWith(\"~\")) return join(homedir(), path.slice(1));\n\treturn resolve(cwd, path);\n}\n\nfunction getBackupDir(): string {\n\tconst backupBase = resolve(homedir(), \".openvibe\", \"backups\");\n\tif (!existsSync(backupBase)) {\n\t\tmkdirSync(backupBase, { recursive: true });\n\t}\n\treturn backupBase;\n}\n\nfunction createBackup(filePath: string): string | null {\n\tif (!existsSync(filePath)) return null;\n\tconst backupDir = getBackupDir();\n\tconst timestamp = Date.now();\n\tconst fileName = basename(filePath);\n\tconst backupPath = resolve(backupDir, `${fileName}.${timestamp}.bak`);\n\ttry {\n\t\twriteFileSync(backupPath, readFileSync(filePath));\n\t\treturn backupPath;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nasync function executeRead(input: Static<typeof ReadOperation>, cwd: string): Promise<OpResult> {\n\tconst startTime = Date.now();\n\ttry {\n\t\tconst absolutePath = resolvePath(input.path, cwd);\n\t\tif (!existsSync(absolutePath)) {\n\t\t\treturn { operation: \"read\", success: false, error: `File not found: ${input.path}`, path: absolutePath };\n\t\t}\n\t\tconst content = readFileSync(absolutePath, \"utf-8\");\n\t\tconst lines = content.split(\"\\n\");\n\t\tconst offset = input.offset ?? 0;\n\t\tconst limit = input.limit ?? 2000;\n\t\tconst selectedLines = lines.slice(offset, offset + limit);\n\t\tconst output = selectedLines.join(\"\\n\");\n\t\treturn {\n\t\t\toperation: \"read\",\n\t\t\tsuccess: true,\n\t\t\toutput: `${input.path}:\\n${output}`,\n\t\t\tpath: absolutePath,\n\t\t\tduration: Date.now() - startTime,\n\t\t\tbytes: Buffer.byteLength(content),\n\t\t};\n\t} catch (e) {\n\t\treturn { operation: \"read\", success: false, error: e instanceof Error ? e.message : String(e) };\n\t}\n}\n\nasync function executeWrite(\n\tinput: Static<typeof WriteOperation>,\n\tcwd: string,\n\tonUpdate?: AgentToolUpdateCallback<UnifiedResult>,\n): Promise<OpResult> {\n\tconst startTime = Date.now();\n\ttry {\n\t\tconst absolutePath = resolvePath(input.path, cwd);\n\t\tconst parentDir = dirname(absolutePath);\n\n\t\tif (!existsSync(parentDir) && (input.createDirs ?? true)) {\n\t\t\tmkdirSync(parentDir, { recursive: true });\n\t\t}\n\n\t\tconst fileExists = existsSync(absolutePath);\n\t\tlet backupPath: string | null = null;\n\t\tif (fileExists) {\n\t\t\tbackupPath = createBackup(absolutePath);\n\t\t}\n\n\t\twriteFileSync(absolutePath, input.content, \"utf-8\");\n\t\tconst bytes = Buffer.byteLength(input.content);\n\n\t\tif (backupPath && existsSync(backupPath)) {\n\t\t\tunlinkSync(backupPath);\n\t\t}\n\n\t\tconst status = fileExists ? \"updated\" : \"created\";\n\t\tonUpdate?.({\n\t\t\tcontent: [{ type: \"text\", text: `[${status === \"created\" ? \"+\" : \"~\"}] ${input.path} (${bytes} bytes)` }],\n\t\t\tdetails: { success: true, total: 1, succeeded: 1, failed: 0, results: [], duration: 0 },\n\t\t});\n\n\t\treturn {\n\t\t\toperation: \"write\",\n\t\t\tsuccess: true,\n\t\t\toutput: `Wrote ${bytes} bytes to ${input.path}`,\n\t\t\tpath: absolutePath,\n\t\t\tduration: Date.now() - startTime,\n\t\t\tbytes,\n\t\t};\n\t} catch (e) {\n\t\treturn { operation: \"write\", success: false, error: e instanceof Error ? e.message : String(e) };\n\t}\n}\n\nasync function executeEdit(\n\tinput: Static<typeof EditOperation>,\n\tcwd: string,\n\tonUpdate?: AgentToolUpdateCallback<UnifiedResult>,\n): Promise<OpResult> {\n\tconst startTime = Date.now();\n\ttry {\n\t\tconst absolutePath = resolvePath(input.path, cwd);\n\t\tif (!existsSync(absolutePath)) {\n\t\t\treturn { operation: \"edit\", success: false, error: `File not found: ${input.path}`, path: absolutePath };\n\t\t}\n\n\t\tconst content = readFileSync(absolutePath, \"utf-8\");\n\t\tlet newContent: string;\n\t\tlet replacements = 0;\n\n\t\tif (input.replaceAll) {\n\t\t\tconst parts = content.split(input.oldText);\n\t\t\treplacements = parts.length - 1;\n\t\t\tnewContent = parts.join(input.newText);\n\t\t} else {\n\t\t\tconst index = content.indexOf(input.oldText);\n\t\t\tif (index === -1) {\n\t\t\t\treturn { operation: \"edit\", success: false, error: `Text not found in ${input.path}` };\n\t\t\t}\n\t\t\tnewContent = content.slice(0, index) + input.newText + content.slice(index + input.oldText.length);\n\t\t\treplacements = 1;\n\t\t}\n\n\t\tconst backupPath = createBackup(absolutePath);\n\t\twriteFileSync(absolutePath, newContent, \"utf-8\");\n\t\tif (backupPath && existsSync(backupPath)) {\n\t\t\tunlinkSync(backupPath);\n\t\t}\n\n\t\tonUpdate?.({\n\t\t\tcontent: [\n\t\t\t\t{ type: \"text\", text: `[~] ${input.path} (${replacements} replacement${replacements > 1 ? \"s\" : \"\"})` },\n\t\t\t],\n\t\t\tdetails: { success: true, total: 1, succeeded: 1, failed: 0, results: [], duration: 0 },\n\t\t});\n\n\t\treturn {\n\t\t\toperation: \"edit\",\n\t\t\tsuccess: true,\n\t\t\toutput: `Replaced ${replacements} occurrence(s) in ${input.path}`,\n\t\t\tpath: absolutePath,\n\t\t\tduration: Date.now() - startTime,\n\t\t};\n\t} catch (e) {\n\t\treturn { operation: \"edit\", success: false, error: e instanceof Error ? e.message : String(e) };\n\t}\n}\n\nasync function executeBash(\n\tinput: Static<typeof BashOperation>,\n\tcwd: string,\n\tsignal: AbortSignal | undefined,\n\tonUpdate?: AgentToolUpdateCallback<UnifiedResult>,\n): Promise<OpResult> {\n\tconst startTime = Date.now();\n\tconst workDir = input.cwd ? resolvePath(input.cwd, cwd) : cwd;\n\n\treturn new Promise((resolveResult) => {\n\t\tconst { shell, args } = getShellConfig();\n\t\tconst stdout: Buffer[] = [];\n\t\tconst stderr: Buffer[] = [];\n\n\t\tconst child = spawn(shell, [...args, input.command], {\n\t\t\tcwd: workDir,\n\t\t\tdetached: true,\n\t\t\tenv: getShellEnv(),\n\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t});\n\n\t\tlet timedOut = false;\n\t\tconst timeoutMs = (input.timeout ?? 120) * 1000;\n\t\tconst timeoutHandle = setTimeout(() => {\n\t\t\ttimedOut = true;\n\t\t\tif (child.pid) killProcessTree(child.pid);\n\t\t}, timeoutMs);\n\n\t\tconst onAbort = () => {\n\t\t\tif (child.pid) killProcessTree(child.pid);\n\t\t};\n\t\tsignal?.addEventListener(\"abort\", onAbort);\n\n\t\tchild.stdout?.on(\"data\", (data: Buffer) => {\n\t\t\tstdout.push(data);\n\t\t\tonUpdate?.({\n\t\t\t\tcontent: [{ type: \"text\", text: data.toString() }],\n\t\t\t\tdetails: { success: true, total: 1, succeeded: 0, failed: 0, results: [], duration: 0 },\n\t\t\t});\n\t\t});\n\t\tchild.stderr?.on(\"data\", (data: Buffer) => stderr.push(data));\n\n\t\tchild.on(\"close\", (code) => {\n\t\t\tclearTimeout(timeoutHandle);\n\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\n\t\t\tconst stdoutText = Buffer.concat(stdout).toString();\n\t\t\tconst stderrText = Buffer.concat(stderr).toString();\n\t\t\tconst output = stdoutText + (stderrText ? `\\nstderr:\\n${stderrText}` : \"\");\n\n\t\t\tresolveResult({\n\t\t\t\toperation: \"bash\",\n\t\t\t\tsuccess: code === 0 && !timedOut,\n\t\t\t\toutput: timedOut ? `Command timed out after ${input.timeout}s\\n${output}` : output,\n\t\t\t\terror: code !== 0 ? `Exit code: ${code}` : undefined,\n\t\t\t\tduration: Date.now() - startTime,\n\t\t\t});\n\t\t});\n\n\t\tchild.on(\"error\", (err) => {\n\t\t\tclearTimeout(timeoutHandle);\n\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\tresolveResult({\n\t\t\t\toperation: \"bash\",\n\t\t\t\tsuccess: false,\n\t\t\t\terror: err.message,\n\t\t\t\tduration: Date.now() - startTime,\n\t\t\t});\n\t\t});\n\t});\n}\n\nasync function executeGrep(input: Static<typeof GrepOperation>, cwd: string): Promise<OpResult> {\n\tconst startTime = Date.now();\n\ttry {\n\t\tconst searchPath = input.path ? resolvePath(input.path, cwd) : cwd;\n\t\tconst pattern = input.i ? new RegExp(input.pattern, \"gi\") : new RegExp(input.pattern, \"g\");\n\t\tconst results: string[] = [];\n\t\tlet count = 0;\n\t\tconst maxResults = input.head_limit ?? 100;\n\n\t\tconst searchFile = (filePath: string) => {\n\t\t\tif (count >= maxResults) return;\n\t\t\ttry {\n\t\t\t\tconst content = readFileSync(filePath, \"utf-8\");\n\t\t\t\tconst lines = content.split(\"\\n\");\n\t\t\t\tfor (let i = 0; i < lines.length && count < maxResults; i++) {\n\t\t\t\t\tif (pattern.test(lines[i])) {\n\t\t\t\t\t\tresults.push(`${filePath}:${i + 1}:${lines[i].trim()}`);\n\t\t\t\t\t\tcount++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch {}\n\t\t};\n\n\t\tconst searchDir = (dir: string) => {\n\t\t\ttry {\n\t\t\t\tconst entries = readdirSync(dir, { withFileTypes: true });\n\t\t\t\tfor (const entry of entries) {\n\t\t\t\t\tif (count >= maxResults) break;\n\t\t\t\t\tconst fullPath = join(dir, entry.name);\n\t\t\t\t\tif (entry.isDirectory()) {\n\t\t\t\t\t\tsearchDir(fullPath);\n\t\t\t\t\t} else if (entry.isFile()) {\n\t\t\t\t\t\tsearchFile(fullPath);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch {}\n\t\t};\n\n\t\tif (existsSync(searchPath)) {\n\t\t\tconst stat = statSync(searchPath);\n\t\t\tif (stat.isDirectory()) {\n\t\t\t\tsearchDir(searchPath);\n\t\t\t} else {\n\t\t\t\tsearchFile(searchPath);\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\toperation: \"grep\",\n\t\t\tsuccess: true,\n\t\t\toutput: results.length > 0 ? results.join(\"\\n\") : \"No matches found\",\n\t\t\tduration: Date.now() - startTime,\n\t\t};\n\t} catch (e) {\n\t\treturn { operation: \"grep\", success: false, error: e instanceof Error ? e.message : String(e) };\n\t}\n}\n\nasync function executeFind(input: Static<typeof FindOperation>, cwd: string): Promise<OpResult> {\n\tconst startTime = Date.now();\n\ttry {\n\t\tconst searchPath = input.path ? resolvePath(input.path, cwd) : cwd;\n\t\tconst results: string[] = [];\n\t\tconst pattern = new RegExp(input.pattern.replace(/\\*/g, \".*\"));\n\n\t\tconst searchDir = (dir: string) => {\n\t\t\ttry {\n\t\t\t\tconst entries = readdirSync(dir, { withFileTypes: true });\n\t\t\t\tfor (const entry of entries) {\n\t\t\t\t\tconst fullPath = join(dir, entry.name);\n\t\t\t\t\tif (pattern.test(entry.name)) {\n\t\t\t\t\t\tresults.push(relative(searchPath, fullPath));\n\t\t\t\t\t}\n\t\t\t\t\tif (entry.isDirectory() && !entry.name.startsWith(\".\")) {\n\t\t\t\t\t\tsearchDir(fullPath);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch {}\n\t\t};\n\n\t\tsearchDir(searchPath);\n\n\t\treturn {\n\t\t\toperation: \"find\",\n\t\t\tsuccess: true,\n\t\t\toutput: results.length > 0 ? results.join(\"\\n\") : \"No files found\",\n\t\t\tduration: Date.now() - startTime,\n\t\t};\n\t} catch (e) {\n\t\treturn { operation: \"find\", success: false, error: e instanceof Error ? e.message : String(e) };\n\t}\n}\n\nasync function executeLs(input: Static<typeof LsOperation>, cwd: string): Promise<OpResult> {\n\tconst startTime = Date.now();\n\ttry {\n\t\tconst listPath = input.path ? resolvePath(input.path, cwd) : cwd;\n\t\tconst entries = readdirSync(listPath, { withFileTypes: true });\n\t\tconst output = entries\n\t\t\t.map((e) => `${e.isDirectory() ? \"d\" : \"-\"} ${e.name}`)\n\t\t\t.sort()\n\t\t\t.join(\"\\n\");\n\n\t\treturn {\n\t\t\toperation: \"ls\",\n\t\t\tsuccess: true,\n\t\t\toutput: `${input.path || \".\"}:\\n${output}`,\n\t\t\tpath: listPath,\n\t\t\tduration: Date.now() - startTime,\n\t\t};\n\t} catch (e) {\n\t\treturn { operation: \"ls\", success: false, error: e instanceof Error ? e.message : String(e) };\n\t}\n}\n\nasync function executeBatchWrite(\n\tinput: Static<typeof BatchWriteOperation>,\n\tcwd: string,\n\tonUpdate?: AgentToolUpdateCallback<UnifiedResult>,\n): Promise<OpResult> {\n\tconst startTime = Date.now();\n\tconst results: OpResult[] = [];\n\tlet succeeded = 0;\n\tlet failed = 0;\n\n\tfor (const file of input.files) {\n\t\tconst result = await executeWrite({ operation: \"write\", path: file.path, content: file.content }, cwd, onUpdate);\n\t\tresults.push(result);\n\t\tif (result.success) succeeded++;\n\t\telse failed++;\n\t}\n\n\treturn {\n\t\toperation: \"batch_write\",\n\t\tsuccess: failed === 0,\n\t\toutput: `Wrote ${succeeded}/${input.files.length} files`,\n\t\terror: failed > 0 ? `${failed} files failed` : undefined,\n\t\tduration: Date.now() - startTime,\n\t};\n}\n\nexport function createUnifiedTool(cwd: string): AgentTool<typeof UnifiedSchema> {\n\treturn {\n\t\tname: \"execute\",\n\t\tlabel: \"execute\",\n\t\tdescription:\n\t\t\t\"Unified tool for all file and shell operations. Supports read, write, edit, bash, grep, find, ls, and batch_write operations. Multiple operations can be executed in sequence or parallel.\",\n\t\tparameters: UnifiedSchema,\n\t\texecute: async (_id, input, signal, onUpdate) => {\n\t\t\tconst startTime = Date.now();\n\t\t\tconst results: OpResult[] = [];\n\t\t\tlet succeeded = 0;\n\t\t\tlet failed = 0;\n\n\t\t\tconst executeOperation = async (op: Static<typeof UnifiedSchema>[\"operations\"][0]): Promise<OpResult> => {\n\t\t\t\tswitch (op.operation) {\n\t\t\t\t\tcase \"read\":\n\t\t\t\t\t\treturn executeRead(op, cwd);\n\t\t\t\t\tcase \"write\":\n\t\t\t\t\t\treturn executeWrite(op, cwd, onUpdate);\n\t\t\t\t\tcase \"edit\":\n\t\t\t\t\t\treturn executeEdit(op, cwd, onUpdate);\n\t\t\t\t\tcase \"bash\":\n\t\t\t\t\t\treturn executeBash(op, cwd, signal, onUpdate);\n\t\t\t\t\tcase \"grep\":\n\t\t\t\t\t\treturn executeGrep(op, cwd);\n\t\t\t\t\tcase \"find\":\n\t\t\t\t\t\treturn executeFind(op, cwd);\n\t\t\t\t\tcase \"ls\":\n\t\t\t\t\t\treturn executeLs(op, cwd);\n\t\t\t\t\tcase \"batch_write\":\n\t\t\t\t\t\treturn executeBatchWrite(op, cwd, onUpdate);\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn { operation: \"unknown\", success: false, error: \"Unknown operation\" };\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tif (input.parallel) {\n\t\t\t\tconst promises = input.operations.map(executeOperation);\n\t\t\t\tconst parallelResults = await Promise.all(promises);\n\t\t\t\tresults.push(...parallelResults);\n\t\t\t} else {\n\t\t\t\tfor (const op of input.operations) {\n\t\t\t\t\tconst result = await executeOperation(op);\n\t\t\t\t\tresults.push(result);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsucceeded = results.filter((r) => r.success).length;\n\t\t\tfailed = results.filter((r) => !r.success).length;\n\t\t\tconst duration = Date.now() - startTime;\n\n\t\t\tconst outputLines: string[] = [\n\t\t\t\t`Execute Report`,\n\t\t\t\t`==============`,\n\t\t\t\t`Total: ${results.length} | Success: ${succeeded} | Failed: ${failed}`,\n\t\t\t\t`Duration: ${duration}ms`,\n\t\t\t\t\"\",\n\t\t\t\t\"Results:\",\n\t\t\t];\n\n\t\t\tfor (const r of results) {\n\t\t\t\tconst icon = r.success ? \"+\" : \"x\";\n\t\t\t\tconst info = r.output ? `: ${r.output.slice(0, 100)}${r.output.length > 100 ? \"...\" : \"\"}` : \"\";\n\t\t\t\tconst error = r.error ? ` - ${r.error}` : \"\";\n\t\t\t\toutputLines.push(` [${icon}] ${r.operation}${info}${error}`);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: outputLines.join(\"\\n\") }],\n\t\t\t\tdetails: {\n\t\t\t\t\tsuccess: failed === 0,\n\t\t\t\t\ttotal: results.length,\n\t\t\t\t\tsucceeded,\n\t\t\t\t\tfailed,\n\t\t\t\t\tresults,\n\t\t\t\t\tduration,\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t};\n}\n\nexport const unifiedTool = createUnifiedTool(process.cwd());\n"]}
|
|
@@ -7,7 +7,7 @@ declare const writeSchema: import("@sinclair/typebox").TObject<{
|
|
|
7
7
|
export type WriteToolInput = Static<typeof writeSchema>;
|
|
8
8
|
export interface WriteOperations {
|
|
9
9
|
writeFile: (absolutePath: string, content: string) => Promise<void>;
|
|
10
|
-
mkdir: (dir: string) =>
|
|
10
|
+
mkdir: (dir: string) => void;
|
|
11
11
|
}
|
|
12
12
|
export interface WriteToolOptions {
|
|
13
13
|
operations?: WriteOperations;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../../src/core/tools/write.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../../src/core/tools/write.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAA2B,MAAM,gCAAgC,CAAC;AACzF,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAMtD,QAAA,MAAM,WAAW;;;EAGf,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,WAAW,CAAC,CAAC;AACxD,MAAM,WAAW,eAAe;IAC/B,SAAS,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAKD,MAAM,WAAW,gBAAgB;IAChC,UAAU,CAAC,EAAE,eAAe,CAAC;CAC7B;AACD,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC,OAAO,WAAW,CAAC,CA+EtG;AACD,eAAO,MAAM,SAAS;;;QAAiC,CAAC","sourcesContent":["import type { AgentTool, AgentToolUpdateCallback } from \"@boxiaolanya2008/pi-agent-core\";\nimport { type Static, Type } from \"@sinclair/typebox\";\nimport { existsSync, mkdirSync } from \"fs\";\nimport { dirname } from \"path\";\nimport { acceleratedWriteFile } from \"./local-accelerator.js\";\nimport { resolveToCwd } from \"./path-utils.js\";\n\nconst writeSchema = Type.Object({\n\tpath: Type.String({ description: \"Path to the file to write (relative or absolute)\" }),\n\tcontent: Type.String({ description: \"Content to write to the file\" }),\n});\nexport type WriteToolInput = Static<typeof writeSchema>;\nexport interface WriteOperations {\n\twriteFile: (absolutePath: string, content: string) => Promise<void>;\n\tmkdir: (dir: string) => void;\n}\nconst defaultWriteOperations: WriteOperations = {\n\twriteFile: (path, content) => acceleratedWriteFile(path, content),\n\tmkdir: (dir) => mkdirSync(dir, { recursive: true }),\n};\nexport interface WriteToolOptions {\n\toperations?: WriteOperations;\n}\nexport function createWriteTool(cwd: string, options?: WriteToolOptions): AgentTool<typeof writeSchema> {\n\tconst ops = options?.operations ?? defaultWriteOperations;\n\treturn {\n\t\tname: \"write\",\n\t\tlabel: \"write\",\n\t\tdescription:\n\t\t\t\"Write content to a file. Creates the file if it doesn't exist, overwrites if it does. Automatically creates parent directories.\",\n\t\tparameters: writeSchema,\n\t\texecute: async (\n\t\t\t_toolCallId: string,\n\t\t\t{ path, content }: { path: string; content: string },\n\t\t\tsignal?: AbortSignal,\n\t\t\tonUpdate?: AgentToolUpdateCallback<undefined>,\n\t\t) => {\n\t\t\tconst absolutePath = resolveToCwd(path, cwd);\n\t\t\tconst dir = dirname(absolutePath);\n\t\t\tconst fileExists = existsSync(absolutePath);\n\t\t\tconst bytes = Buffer.byteLength(content, \"utf-8\");\n\n\t\t\tonUpdate?.({\n\t\t\t\tcontent: [{ type: \"text\", text: `Writing ${bytes} bytes to ${path}...` }],\n\t\t\t\tdetails: undefined,\n\t\t\t});\n\n\t\t\treturn new Promise<{ content: Array<{ type: \"text\"; text: string }>; details: undefined }>(\n\t\t\t\t(resolve, reject) => {\n\t\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tlet aborted = false;\n\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\taborted = true;\n\t\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\t};\n\t\t\t\t\tif (signal) {\n\t\t\t\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t\t}\n\t\t\t\t\t(async () => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tops.mkdir(dir);\n\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tawait ops.writeFile(absolutePath, content);\n\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst status = fileExists ? \"updated\" : \"created\";\n\t\t\t\t\t\t\tonUpdate?.({\n\t\t\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t\t\t{ type: \"text\", text: `[${status === \"created\" ? \"+\" : \"~\"}] ${path} (${bytes} bytes)` },\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\tdetails: undefined,\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t\t\t{ type: \"text\", text: `[${status === \"created\" ? \"+\" : \"~\"}] ${path} (${bytes} bytes)` },\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\tdetails: undefined,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} catch (error: any) {\n\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!aborted) {\n\t\t\t\t\t\t\t\treject(error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t})();\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t};\n}\nexport const writeTool = createWriteTool(process.cwd());\n"]}
|
package/dist/core/tools/write.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Type } from "@sinclair/typebox";
|
|
2
|
-
import {
|
|
2
|
+
import { existsSync, mkdirSync } from "fs";
|
|
3
3
|
import { dirname } from "path";
|
|
4
4
|
import { acceleratedWriteFile } from "./local-accelerator.js";
|
|
5
5
|
import { resolveToCwd } from "./path-utils.js";
|
|
@@ -9,7 +9,7 @@ const writeSchema = Type.Object({
|
|
|
9
9
|
});
|
|
10
10
|
const defaultWriteOperations = {
|
|
11
11
|
writeFile: (path, content) => acceleratedWriteFile(path, content),
|
|
12
|
-
mkdir: (dir) =>
|
|
12
|
+
mkdir: (dir) => mkdirSync(dir, { recursive: true }),
|
|
13
13
|
};
|
|
14
14
|
export function createWriteTool(cwd, options) {
|
|
15
15
|
const ops = options?.operations ?? defaultWriteOperations;
|
|
@@ -18,9 +18,15 @@ export function createWriteTool(cwd, options) {
|
|
|
18
18
|
label: "write",
|
|
19
19
|
description: "Write content to a file. Creates the file if it doesn't exist, overwrites if it does. Automatically creates parent directories.",
|
|
20
20
|
parameters: writeSchema,
|
|
21
|
-
execute: async (_toolCallId, { path, content }, signal) => {
|
|
21
|
+
execute: async (_toolCallId, { path, content }, signal, onUpdate) => {
|
|
22
22
|
const absolutePath = resolveToCwd(path, cwd);
|
|
23
23
|
const dir = dirname(absolutePath);
|
|
24
|
+
const fileExists = existsSync(absolutePath);
|
|
25
|
+
const bytes = Buffer.byteLength(content, "utf-8");
|
|
26
|
+
onUpdate?.({
|
|
27
|
+
content: [{ type: "text", text: `Writing ${bytes} bytes to ${path}...` }],
|
|
28
|
+
details: undefined,
|
|
29
|
+
});
|
|
24
30
|
return new Promise((resolve, reject) => {
|
|
25
31
|
if (signal?.aborted) {
|
|
26
32
|
reject(new Error("Operation aborted"));
|
|
@@ -36,7 +42,7 @@ export function createWriteTool(cwd, options) {
|
|
|
36
42
|
}
|
|
37
43
|
(async () => {
|
|
38
44
|
try {
|
|
39
|
-
|
|
45
|
+
ops.mkdir(dir);
|
|
40
46
|
if (aborted) {
|
|
41
47
|
return;
|
|
42
48
|
}
|
|
@@ -47,8 +53,17 @@ export function createWriteTool(cwd, options) {
|
|
|
47
53
|
if (signal) {
|
|
48
54
|
signal.removeEventListener("abort", onAbort);
|
|
49
55
|
}
|
|
56
|
+
const status = fileExists ? "updated" : "created";
|
|
57
|
+
onUpdate?.({
|
|
58
|
+
content: [
|
|
59
|
+
{ type: "text", text: `[${status === "created" ? "+" : "~"}] ${path} (${bytes} bytes)` },
|
|
60
|
+
],
|
|
61
|
+
details: undefined,
|
|
62
|
+
});
|
|
50
63
|
resolve({
|
|
51
|
-
content: [
|
|
64
|
+
content: [
|
|
65
|
+
{ type: "text", text: `[${status === "created" ? "+" : "~"}] ${path} (${bytes} bytes)` },
|
|
66
|
+
],
|
|
52
67
|
details: undefined,
|
|
53
68
|
});
|
|
54
69
|
}
|