openvibe 0.63.1 → 0.63.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/CHANGELOG.md +92 -2
- 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 +7 -17
- 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,212 @@
|
|
|
1
|
+
import { Type } from "@sinclair/typebox";
|
|
2
|
+
import { addTodo, completeTodo, listTodos, removeTodo, searchTodos, uncompleteTodo, } from "../todo-manager.js";
|
|
3
|
+
const todoAddSchema = Type.Object({
|
|
4
|
+
text: Type.String({ description: "The todo item text" }),
|
|
5
|
+
priority: Type.Optional(Type.Union([Type.Literal("low"), Type.Literal("medium"), Type.Literal("high")], {
|
|
6
|
+
description: "Priority level (default: medium)",
|
|
7
|
+
})),
|
|
8
|
+
tags: Type.Optional(Type.Array(Type.String(), { description: "Tags for categorization" })),
|
|
9
|
+
});
|
|
10
|
+
const todoCompleteSchema = Type.Object({
|
|
11
|
+
idOrText: Type.String({
|
|
12
|
+
description: "The todo ID or exact text to mark as completed",
|
|
13
|
+
}),
|
|
14
|
+
});
|
|
15
|
+
const todoUncompleteSchema = Type.Object({
|
|
16
|
+
idOrText: Type.String({
|
|
17
|
+
description: "The todo ID or exact text to mark as not completed",
|
|
18
|
+
}),
|
|
19
|
+
});
|
|
20
|
+
const todoRemoveSchema = Type.Object({
|
|
21
|
+
idOrText: Type.String({
|
|
22
|
+
description: "The todo ID or exact text to remove",
|
|
23
|
+
}),
|
|
24
|
+
});
|
|
25
|
+
const todoListSchema = Type.Object({
|
|
26
|
+
filter: Type.Optional(Type.Union([Type.Literal("all"), Type.Literal("active"), Type.Literal("completed")], {
|
|
27
|
+
description: "Filter option (default: all)",
|
|
28
|
+
})),
|
|
29
|
+
});
|
|
30
|
+
const todoSearchSchema = Type.Object({
|
|
31
|
+
query: Type.String({ description: "Search query for todo text or tags" }),
|
|
32
|
+
});
|
|
33
|
+
function formatTodoItem(item) {
|
|
34
|
+
const status = item.completed ? "[x]" : "[ ]";
|
|
35
|
+
const priority = item.priority === "high" ? "!!!" : item.priority === "low" ? "!" : "!!";
|
|
36
|
+
const tags = item.tags.length > 0 ? ` (${item.tags.join(", ")})` : "";
|
|
37
|
+
return `${status} ${priority} ${item.text}${tags}`;
|
|
38
|
+
}
|
|
39
|
+
export const todoAddTool = {
|
|
40
|
+
name: "todo_add",
|
|
41
|
+
label: "todo_add",
|
|
42
|
+
description: "Add a new todo item to the list. Use this to track tasks, reminders, or action items.",
|
|
43
|
+
parameters: todoAddSchema,
|
|
44
|
+
execute: async (_id, { text, priority, tags }) => {
|
|
45
|
+
const item = addTodo(text, { priority, tags });
|
|
46
|
+
return {
|
|
47
|
+
content: [
|
|
48
|
+
{
|
|
49
|
+
type: "text",
|
|
50
|
+
text: `Added todo: ${formatTodoItem(item)}`,
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
details: { item },
|
|
54
|
+
};
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
export const todoCompleteTool = {
|
|
58
|
+
name: "todo_complete",
|
|
59
|
+
label: "todo_complete",
|
|
60
|
+
description: "Mark a todo item as completed. Provide the todo ID or exact text.",
|
|
61
|
+
parameters: todoCompleteSchema,
|
|
62
|
+
execute: async (_id, { idOrText }) => {
|
|
63
|
+
const item = completeTodo(idOrText);
|
|
64
|
+
if (!item) {
|
|
65
|
+
return {
|
|
66
|
+
content: [
|
|
67
|
+
{
|
|
68
|
+
type: "text",
|
|
69
|
+
text: `Could not find active todo matching "${idOrText}"`,
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
details: undefined,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
content: [
|
|
77
|
+
{
|
|
78
|
+
type: "text",
|
|
79
|
+
text: `Completed: ${formatTodoItem(item)}`,
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
details: { item },
|
|
83
|
+
};
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
export const todoUncompleteTool = {
|
|
87
|
+
name: "todo_uncomplete",
|
|
88
|
+
label: "todo_uncomplete",
|
|
89
|
+
description: "Mark a completed todo item as not completed. Provide the todo ID or exact text.",
|
|
90
|
+
parameters: todoUncompleteSchema,
|
|
91
|
+
execute: async (_id, { idOrText }) => {
|
|
92
|
+
const item = uncompleteTodo(idOrText);
|
|
93
|
+
if (!item) {
|
|
94
|
+
return {
|
|
95
|
+
content: [
|
|
96
|
+
{
|
|
97
|
+
type: "text",
|
|
98
|
+
text: `Could not find completed todo matching "${idOrText}"`,
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
details: undefined,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
content: [
|
|
106
|
+
{
|
|
107
|
+
type: "text",
|
|
108
|
+
text: `Reopened: ${formatTodoItem(item)}`,
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
details: { item },
|
|
112
|
+
};
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
export const todoRemoveTool = {
|
|
116
|
+
name: "todo_remove",
|
|
117
|
+
label: "todo_remove",
|
|
118
|
+
description: "Remove a todo item from the list. Provide the todo ID or exact text.",
|
|
119
|
+
parameters: todoRemoveSchema,
|
|
120
|
+
execute: async (_id, { idOrText }) => {
|
|
121
|
+
const item = removeTodo(idOrText);
|
|
122
|
+
if (!item) {
|
|
123
|
+
return {
|
|
124
|
+
content: [
|
|
125
|
+
{
|
|
126
|
+
type: "text",
|
|
127
|
+
text: `Could not find todo matching "${idOrText}"`,
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
details: undefined,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
content: [
|
|
135
|
+
{
|
|
136
|
+
type: "text",
|
|
137
|
+
text: `Removed: ${formatTodoItem(item)}`,
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
details: { item },
|
|
141
|
+
};
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
export const todoListTool = {
|
|
145
|
+
name: "todo_list",
|
|
146
|
+
label: "todo_list",
|
|
147
|
+
description: "List all todo items. Can filter by all, active (not completed), or completed.",
|
|
148
|
+
parameters: todoListSchema,
|
|
149
|
+
execute: async (_id, { filter }) => {
|
|
150
|
+
const items = listTodos(filter);
|
|
151
|
+
if (items.length === 0) {
|
|
152
|
+
return {
|
|
153
|
+
content: [
|
|
154
|
+
{
|
|
155
|
+
type: "text",
|
|
156
|
+
text: "No todo items found.",
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
details: { items: [] },
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
const lines = items.map(formatTodoItem);
|
|
163
|
+
return {
|
|
164
|
+
content: [
|
|
165
|
+
{
|
|
166
|
+
type: "text",
|
|
167
|
+
text: lines.join("\n"),
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
details: { items },
|
|
171
|
+
};
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
export const todoSearchTool = {
|
|
175
|
+
name: "todo_search",
|
|
176
|
+
label: "todo_search",
|
|
177
|
+
description: "Search for todo items by text content or tags.",
|
|
178
|
+
parameters: todoSearchSchema,
|
|
179
|
+
execute: async (_id, { query }) => {
|
|
180
|
+
const items = searchTodos(query);
|
|
181
|
+
if (items.length === 0) {
|
|
182
|
+
return {
|
|
183
|
+
content: [
|
|
184
|
+
{
|
|
185
|
+
type: "text",
|
|
186
|
+
text: `No todos found matching "${query}".`,
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
details: { items: [] },
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
const lines = items.map(formatTodoItem);
|
|
193
|
+
return {
|
|
194
|
+
content: [
|
|
195
|
+
{
|
|
196
|
+
type: "text",
|
|
197
|
+
text: `Found ${items.length} todo(s) matching "${query}":\n${lines.join("\n")}`,
|
|
198
|
+
},
|
|
199
|
+
],
|
|
200
|
+
details: { items },
|
|
201
|
+
};
|
|
202
|
+
},
|
|
203
|
+
};
|
|
204
|
+
export const todoTools = [
|
|
205
|
+
todoAddTool,
|
|
206
|
+
todoCompleteTool,
|
|
207
|
+
todoUncompleteTool,
|
|
208
|
+
todoRemoveTool,
|
|
209
|
+
todoListTool,
|
|
210
|
+
todoSearchTool,
|
|
211
|
+
];
|
|
212
|
+
//# sourceMappingURL=todo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"todo.js","sourceRoot":"","sources":["../../../src/core/tools/todo.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentTool } from \"@boxiaolanya2008/pi-agent-core\";\nimport { type Static, Type } from \"@sinclair/typebox\";\nimport {\n\taddTodo,\n\tcompleteTodo,\n\tlistTodos,\n\ttype loadTodos,\n\tremoveTodo,\n\tsearchTodos,\n\tuncompleteTodo,\n} from \"../todo-manager.js\";\n\nconst todoAddSchema = Type.Object({\n\ttext: Type.String({ description: \"The todo item text\" }),\n\tpriority: Type.Optional(\n\t\tType.Union([Type.Literal(\"low\"), Type.Literal(\"medium\"), Type.Literal(\"high\")], {\n\t\t\tdescription: \"Priority level (default: medium)\",\n\t\t}),\n\t),\n\ttags: Type.Optional(Type.Array(Type.String(), { description: \"Tags for categorization\" })),\n});\n\nconst todoCompleteSchema = Type.Object({\n\tidOrText: Type.String({\n\t\tdescription: \"The todo ID or exact text to mark as completed\",\n\t}),\n});\n\nconst todoUncompleteSchema = Type.Object({\n\tidOrText: Type.String({\n\t\tdescription: \"The todo ID or exact text to mark as not completed\",\n\t}),\n});\n\nconst todoRemoveSchema = Type.Object({\n\tidOrText: Type.String({\n\t\tdescription: \"The todo ID or exact text to remove\",\n\t}),\n});\n\nconst todoListSchema = Type.Object({\n\tfilter: Type.Optional(\n\t\tType.Union([Type.Literal(\"all\"), Type.Literal(\"active\"), Type.Literal(\"completed\")], {\n\t\t\tdescription: \"Filter option (default: all)\",\n\t\t}),\n\t),\n});\n\nconst todoSearchSchema = Type.Object({\n\tquery: Type.String({ description: \"Search query for todo text or tags\" }),\n});\n\nexport type TodoAddInput = Static<typeof todoAddSchema>;\nexport type TodoCompleteInput = Static<typeof todoCompleteSchema>;\nexport type TodoUncompleteInput = Static<typeof todoUncompleteSchema>;\nexport type TodoRemoveInput = Static<typeof todoRemoveSchema>;\nexport type TodoListInput = Static<typeof todoListSchema>;\nexport type TodoSearchInput = Static<typeof todoSearchSchema>;\n\nfunction formatTodoItem(item: ReturnType<typeof loadTodos>[\"items\"][0]): string {\n\tconst status = item.completed ? \"[x]\" : \"[ ]\";\n\tconst priority = item.priority === \"high\" ? \"!!!\" : item.priority === \"low\" ? \"!\" : \"!!\";\n\tconst tags = item.tags.length > 0 ? ` (${item.tags.join(\", \")})` : \"\";\n\treturn `${status} ${priority} ${item.text}${tags}`;\n}\n\nexport const todoAddTool: AgentTool<typeof todoAddSchema> = {\n\tname: \"todo_add\",\n\tlabel: \"todo_add\",\n\tdescription: \"Add a new todo item to the list. Use this to track tasks, reminders, or action items.\",\n\tparameters: todoAddSchema,\n\texecute: async (_id, { text, priority, tags }) => {\n\t\tconst item = addTodo(text, { priority, tags });\n\t\treturn {\n\t\t\tcontent: [\n\t\t\t\t{\n\t\t\t\t\ttype: \"text\",\n\t\t\t\t\ttext: `Added todo: ${formatTodoItem(item)}`,\n\t\t\t\t},\n\t\t\t],\n\t\t\tdetails: { item },\n\t\t};\n\t},\n};\n\nexport const todoCompleteTool: AgentTool<typeof todoCompleteSchema> = {\n\tname: \"todo_complete\",\n\tlabel: \"todo_complete\",\n\tdescription: \"Mark a todo item as completed. Provide the todo ID or exact text.\",\n\tparameters: todoCompleteSchema,\n\texecute: async (_id, { idOrText }) => {\n\t\tconst item = completeTodo(idOrText);\n\t\tif (!item) {\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: `Could not find active todo matching \"${idOrText}\"`,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdetails: undefined,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tcontent: [\n\t\t\t\t{\n\t\t\t\t\ttype: \"text\",\n\t\t\t\t\ttext: `Completed: ${formatTodoItem(item)}`,\n\t\t\t\t},\n\t\t\t],\n\t\t\tdetails: { item },\n\t\t};\n\t},\n};\n\nexport const todoUncompleteTool: AgentTool<typeof todoUncompleteSchema> = {\n\tname: \"todo_uncomplete\",\n\tlabel: \"todo_uncomplete\",\n\tdescription: \"Mark a completed todo item as not completed. Provide the todo ID or exact text.\",\n\tparameters: todoUncompleteSchema,\n\texecute: async (_id, { idOrText }) => {\n\t\tconst item = uncompleteTodo(idOrText);\n\t\tif (!item) {\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: `Could not find completed todo matching \"${idOrText}\"`,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdetails: undefined,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tcontent: [\n\t\t\t\t{\n\t\t\t\t\ttype: \"text\",\n\t\t\t\t\ttext: `Reopened: ${formatTodoItem(item)}`,\n\t\t\t\t},\n\t\t\t],\n\t\t\tdetails: { item },\n\t\t};\n\t},\n};\n\nexport const todoRemoveTool: AgentTool<typeof todoRemoveSchema> = {\n\tname: \"todo_remove\",\n\tlabel: \"todo_remove\",\n\tdescription: \"Remove a todo item from the list. Provide the todo ID or exact text.\",\n\tparameters: todoRemoveSchema,\n\texecute: async (_id, { idOrText }) => {\n\t\tconst item = removeTodo(idOrText);\n\t\tif (!item) {\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: `Could not find todo matching \"${idOrText}\"`,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdetails: undefined,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tcontent: [\n\t\t\t\t{\n\t\t\t\t\ttype: \"text\",\n\t\t\t\t\ttext: `Removed: ${formatTodoItem(item)}`,\n\t\t\t\t},\n\t\t\t],\n\t\t\tdetails: { item },\n\t\t};\n\t},\n};\n\nexport const todoListTool: AgentTool<typeof todoListSchema> = {\n\tname: \"todo_list\",\n\tlabel: \"todo_list\",\n\tdescription: \"List all todo items. Can filter by all, active (not completed), or completed.\",\n\tparameters: todoListSchema,\n\texecute: async (_id, { filter }) => {\n\t\tconst items = listTodos(filter);\n\t\tif (items.length === 0) {\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: \"No todo items found.\",\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdetails: { items: [] },\n\t\t\t};\n\t\t}\n\t\tconst lines = items.map(formatTodoItem);\n\t\treturn {\n\t\t\tcontent: [\n\t\t\t\t{\n\t\t\t\t\ttype: \"text\",\n\t\t\t\t\ttext: lines.join(\"\\n\"),\n\t\t\t\t},\n\t\t\t],\n\t\t\tdetails: { items },\n\t\t};\n\t},\n};\n\nexport const todoSearchTool: AgentTool<typeof todoSearchSchema> = {\n\tname: \"todo_search\",\n\tlabel: \"todo_search\",\n\tdescription: \"Search for todo items by text content or tags.\",\n\tparameters: todoSearchSchema,\n\texecute: async (_id, { query }) => {\n\t\tconst items = searchTodos(query);\n\t\tif (items.length === 0) {\n\t\t\treturn {\n\t\t\t\tcontent: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\ttext: `No todos found matching \"${query}\".`,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdetails: { items: [] },\n\t\t\t};\n\t\t}\n\t\tconst lines = items.map(formatTodoItem);\n\t\treturn {\n\t\t\tcontent: [\n\t\t\t\t{\n\t\t\t\t\ttype: \"text\",\n\t\t\t\t\ttext: `Found ${items.length} todo(s) matching \"${query}\":\\n${lines.join(\"\\n\")}`,\n\t\t\t\t},\n\t\t\t],\n\t\t\tdetails: { items },\n\t\t};\n\t},\n};\n\nexport const todoTools = [\n\ttodoAddTool,\n\ttodoCompleteTool,\n\ttodoUncompleteTool,\n\ttodoRemoveTool,\n\ttodoListTool,\n\ttodoSearchTool,\n];\n"]}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import type { AgentTool } from "@boxiaolanya2008/pi-agent-core";
|
|
2
|
+
import { type Static } from "@sinclair/typebox";
|
|
3
|
+
declare const UnifiedSchema: import("@sinclair/typebox").TObject<{
|
|
4
|
+
operations: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TObject<{
|
|
5
|
+
operation: import("@sinclair/typebox").TLiteral<"read">;
|
|
6
|
+
path: import("@sinclair/typebox").TString;
|
|
7
|
+
offset: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
8
|
+
limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
9
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
10
|
+
operation: import("@sinclair/typebox").TLiteral<"write">;
|
|
11
|
+
path: import("@sinclair/typebox").TString;
|
|
12
|
+
content: import("@sinclair/typebox").TString;
|
|
13
|
+
createDirs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
14
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
15
|
+
operation: import("@sinclair/typebox").TLiteral<"edit">;
|
|
16
|
+
path: import("@sinclair/typebox").TString;
|
|
17
|
+
oldText: import("@sinclair/typebox").TString;
|
|
18
|
+
newText: import("@sinclair/typebox").TString;
|
|
19
|
+
replaceAll: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
20
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
21
|
+
operation: import("@sinclair/typebox").TLiteral<"bash">;
|
|
22
|
+
command: import("@sinclair/typebox").TString;
|
|
23
|
+
timeout: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
24
|
+
cwd: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
25
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
26
|
+
operation: import("@sinclair/typebox").TLiteral<"grep">;
|
|
27
|
+
pattern: import("@sinclair/typebox").TString;
|
|
28
|
+
path: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
29
|
+
type: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
30
|
+
glob: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
31
|
+
i: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
32
|
+
head_limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
33
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
34
|
+
operation: import("@sinclair/typebox").TLiteral<"find">;
|
|
35
|
+
pattern: import("@sinclair/typebox").TString;
|
|
36
|
+
path: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
37
|
+
type: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
38
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
39
|
+
operation: import("@sinclair/typebox").TLiteral<"ls">;
|
|
40
|
+
path: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
41
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
42
|
+
operation: import("@sinclair/typebox").TLiteral<"batch_write">;
|
|
43
|
+
files: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
44
|
+
path: import("@sinclair/typebox").TString;
|
|
45
|
+
content: import("@sinclair/typebox").TString;
|
|
46
|
+
}>>;
|
|
47
|
+
atomic: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
48
|
+
backup: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
49
|
+
}>]>>;
|
|
50
|
+
parallel: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
51
|
+
}>;
|
|
52
|
+
export type UnifiedInput = Static<typeof UnifiedSchema>;
|
|
53
|
+
export { UnifiedSchema };
|
|
54
|
+
interface OpResult {
|
|
55
|
+
operation: string;
|
|
56
|
+
success: boolean;
|
|
57
|
+
output?: string;
|
|
58
|
+
error?: string;
|
|
59
|
+
path?: string;
|
|
60
|
+
duration?: number;
|
|
61
|
+
bytes?: number;
|
|
62
|
+
}
|
|
63
|
+
export interface UnifiedResult {
|
|
64
|
+
success: boolean;
|
|
65
|
+
total: number;
|
|
66
|
+
succeeded: number;
|
|
67
|
+
failed: number;
|
|
68
|
+
results: OpResult[];
|
|
69
|
+
duration: number;
|
|
70
|
+
}
|
|
71
|
+
export declare function createUnifiedTool(cwd: string): AgentTool<typeof UnifiedSchema>;
|
|
72
|
+
export declare const unifiedTool: AgentTool<import("@sinclair/typebox").TObject<{
|
|
73
|
+
operations: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TObject<{
|
|
74
|
+
operation: import("@sinclair/typebox").TLiteral<"read">;
|
|
75
|
+
path: import("@sinclair/typebox").TString;
|
|
76
|
+
offset: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
77
|
+
limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
78
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
79
|
+
operation: import("@sinclair/typebox").TLiteral<"write">;
|
|
80
|
+
path: import("@sinclair/typebox").TString;
|
|
81
|
+
content: import("@sinclair/typebox").TString;
|
|
82
|
+
createDirs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
83
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
84
|
+
operation: import("@sinclair/typebox").TLiteral<"edit">;
|
|
85
|
+
path: import("@sinclair/typebox").TString;
|
|
86
|
+
oldText: import("@sinclair/typebox").TString;
|
|
87
|
+
newText: import("@sinclair/typebox").TString;
|
|
88
|
+
replaceAll: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
89
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
90
|
+
operation: import("@sinclair/typebox").TLiteral<"bash">;
|
|
91
|
+
command: import("@sinclair/typebox").TString;
|
|
92
|
+
timeout: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
93
|
+
cwd: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
94
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
95
|
+
operation: import("@sinclair/typebox").TLiteral<"grep">;
|
|
96
|
+
pattern: import("@sinclair/typebox").TString;
|
|
97
|
+
path: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
98
|
+
type: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
99
|
+
glob: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
100
|
+
i: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
101
|
+
head_limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
102
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
103
|
+
operation: import("@sinclair/typebox").TLiteral<"find">;
|
|
104
|
+
pattern: import("@sinclair/typebox").TString;
|
|
105
|
+
path: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
106
|
+
type: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
107
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
108
|
+
operation: import("@sinclair/typebox").TLiteral<"ls">;
|
|
109
|
+
path: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
110
|
+
}>, import("@sinclair/typebox").TObject<{
|
|
111
|
+
operation: import("@sinclair/typebox").TLiteral<"batch_write">;
|
|
112
|
+
files: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
113
|
+
path: import("@sinclair/typebox").TString;
|
|
114
|
+
content: import("@sinclair/typebox").TString;
|
|
115
|
+
}>>;
|
|
116
|
+
atomic: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
117
|
+
backup: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
118
|
+
}>]>>;
|
|
119
|
+
parallel: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
120
|
+
}>, any>;
|
|
121
|
+
//# sourceMappingURL=unified.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unified.d.ts","sourceRoot":"","sources":["../../../src/core/tools/unified.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAA2B,MAAM,gCAAgC,CAAC;AACzF,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAsEtD,QAAA,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAejB,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,aAAa,CAAC,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,CAAC;AAEzB,UAAU,QAAQ;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,QAAQ,EAAE,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CACjB;AAiXD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC,OAAO,aAAa,CAAC,CAgF9E;AAED,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAAmC,CAAC","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"]}
|