apexbot 1.0.1 → 1.0.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.
@@ -0,0 +1,352 @@
1
+ "use strict";
2
+ /**
3
+ * File System Tools
4
+ *
5
+ * Read, write, list, and manage files and directories.
6
+ */
7
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
20
+ }) : function(o, v) {
21
+ o["default"] = v;
22
+ });
23
+ var __importStar = (this && this.__importStar) || (function () {
24
+ var ownKeys = function(o) {
25
+ ownKeys = Object.getOwnPropertyNames || function (o) {
26
+ var ar = [];
27
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
+ return ar;
29
+ };
30
+ return ownKeys(o);
31
+ };
32
+ return function (mod) {
33
+ if (mod && mod.__esModule) return mod;
34
+ var result = {};
35
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
+ __setModuleDefault(result, mod);
37
+ return result;
38
+ };
39
+ })();
40
+ Object.defineProperty(exports, "__esModule", { value: true });
41
+ exports.editFileTool = exports.deleteFileTool = exports.listDirTool = exports.writeFileTool = exports.readFileTool = void 0;
42
+ exports.registerFileTools = registerFileTools;
43
+ const fs = __importStar(require("fs/promises"));
44
+ const path = __importStar(require("path"));
45
+ const index_1 = require("./index");
46
+ // Read File Tool
47
+ const readFileTool = {
48
+ definition: {
49
+ name: 'read_file',
50
+ description: 'Read the contents of a file. Supports text files.',
51
+ category: 'core',
52
+ parameters: [
53
+ {
54
+ name: 'path',
55
+ type: 'string',
56
+ description: 'Path to the file to read',
57
+ required: true,
58
+ },
59
+ {
60
+ name: 'encoding',
61
+ type: 'string',
62
+ description: 'File encoding (default: utf-8)',
63
+ required: false,
64
+ default: 'utf-8',
65
+ },
66
+ ],
67
+ returns: 'File contents as string',
68
+ },
69
+ async execute(params, context) {
70
+ const { path: filePath, encoding = 'utf-8' } = params;
71
+ if (!filePath) {
72
+ return { success: false, error: 'Path is required' };
73
+ }
74
+ try {
75
+ const fullPath = path.resolve(context.workspaceDir || process.cwd(), filePath);
76
+ const content = await fs.readFile(fullPath, encoding);
77
+ return {
78
+ success: true,
79
+ data: {
80
+ path: fullPath,
81
+ content,
82
+ size: content.length,
83
+ },
84
+ };
85
+ }
86
+ catch (error) {
87
+ return { success: false, error: error.message };
88
+ }
89
+ },
90
+ };
91
+ exports.readFileTool = readFileTool;
92
+ // Write File Tool
93
+ const writeFileTool = {
94
+ definition: {
95
+ name: 'write_file',
96
+ description: 'Write content to a file. Creates the file if it does not exist.',
97
+ category: 'core',
98
+ parameters: [
99
+ {
100
+ name: 'path',
101
+ type: 'string',
102
+ description: 'Path to the file to write',
103
+ required: true,
104
+ },
105
+ {
106
+ name: 'content',
107
+ type: 'string',
108
+ description: 'Content to write to the file',
109
+ required: true,
110
+ },
111
+ {
112
+ name: 'append',
113
+ type: 'boolean',
114
+ description: 'Append to file instead of overwriting',
115
+ required: false,
116
+ default: false,
117
+ },
118
+ ],
119
+ returns: 'Success confirmation',
120
+ },
121
+ async execute(params, context) {
122
+ const { path: filePath, content, append = false } = params;
123
+ if (!filePath) {
124
+ return { success: false, error: 'Path is required' };
125
+ }
126
+ try {
127
+ const fullPath = path.resolve(context.workspaceDir || process.cwd(), filePath);
128
+ // Ensure directory exists
129
+ const dir = path.dirname(fullPath);
130
+ await fs.mkdir(dir, { recursive: true });
131
+ if (append) {
132
+ await fs.appendFile(fullPath, content);
133
+ }
134
+ else {
135
+ await fs.writeFile(fullPath, content);
136
+ }
137
+ return {
138
+ success: true,
139
+ data: {
140
+ path: fullPath,
141
+ bytesWritten: content.length,
142
+ append,
143
+ },
144
+ };
145
+ }
146
+ catch (error) {
147
+ return { success: false, error: error.message };
148
+ }
149
+ },
150
+ };
151
+ exports.writeFileTool = writeFileTool;
152
+ // List Directory Tool
153
+ const listDirTool = {
154
+ definition: {
155
+ name: 'list_dir',
156
+ description: 'List files and directories in a path.',
157
+ category: 'core',
158
+ parameters: [
159
+ {
160
+ name: 'path',
161
+ type: 'string',
162
+ description: 'Directory path to list',
163
+ required: false,
164
+ default: '.',
165
+ },
166
+ {
167
+ name: 'recursive',
168
+ type: 'boolean',
169
+ description: 'List recursively',
170
+ required: false,
171
+ default: false,
172
+ },
173
+ ],
174
+ returns: 'Array of file/directory entries',
175
+ },
176
+ async execute(params, context) {
177
+ const { path: dirPath = '.', recursive = false } = params;
178
+ try {
179
+ const fullPath = path.resolve(context.workspaceDir || process.cwd(), dirPath);
180
+ async function listRecursive(dir) {
181
+ const entries = await fs.readdir(dir, { withFileTypes: true });
182
+ const results = [];
183
+ for (const entry of entries) {
184
+ const entryPath = path.join(dir, entry.name);
185
+ const relativePath = path.relative(fullPath, entryPath);
186
+ const info = {
187
+ name: entry.name,
188
+ path: relativePath,
189
+ isDirectory: entry.isDirectory(),
190
+ isFile: entry.isFile(),
191
+ };
192
+ if (entry.isFile()) {
193
+ const stat = await fs.stat(entryPath);
194
+ info.size = stat.size;
195
+ info.modified = stat.mtime;
196
+ }
197
+ results.push(info);
198
+ if (recursive && entry.isDirectory()) {
199
+ const subEntries = await listRecursive(entryPath);
200
+ results.push(...subEntries);
201
+ }
202
+ }
203
+ return results;
204
+ }
205
+ const entries = await listRecursive(fullPath);
206
+ return {
207
+ success: true,
208
+ data: {
209
+ path: fullPath,
210
+ entries,
211
+ count: entries.length,
212
+ },
213
+ };
214
+ }
215
+ catch (error) {
216
+ return { success: false, error: error.message };
217
+ }
218
+ },
219
+ };
220
+ exports.listDirTool = listDirTool;
221
+ // Delete File Tool
222
+ const deleteFileTool = {
223
+ definition: {
224
+ name: 'delete_file',
225
+ description: 'Delete a file or directory.',
226
+ category: 'core',
227
+ parameters: [
228
+ {
229
+ name: 'path',
230
+ type: 'string',
231
+ description: 'Path to delete',
232
+ required: true,
233
+ },
234
+ {
235
+ name: 'recursive',
236
+ type: 'boolean',
237
+ description: 'Delete directories recursively',
238
+ required: false,
239
+ default: false,
240
+ },
241
+ ],
242
+ returns: 'Success confirmation',
243
+ },
244
+ async execute(params, context) {
245
+ const { path: filePath, recursive = false } = params;
246
+ if (!filePath) {
247
+ return { success: false, error: 'Path is required' };
248
+ }
249
+ try {
250
+ const fullPath = path.resolve(context.workspaceDir || process.cwd(), filePath);
251
+ const stat = await fs.stat(fullPath);
252
+ if (stat.isDirectory()) {
253
+ if (!recursive) {
254
+ return { success: false, error: 'Use recursive: true to delete directories' };
255
+ }
256
+ await fs.rm(fullPath, { recursive: true, force: true });
257
+ }
258
+ else {
259
+ await fs.unlink(fullPath);
260
+ }
261
+ return {
262
+ success: true,
263
+ data: {
264
+ path: fullPath,
265
+ deleted: true,
266
+ },
267
+ };
268
+ }
269
+ catch (error) {
270
+ return { success: false, error: error.message };
271
+ }
272
+ },
273
+ };
274
+ exports.deleteFileTool = deleteFileTool;
275
+ // Edit File Tool (search and replace)
276
+ const editFileTool = {
277
+ definition: {
278
+ name: 'edit_file',
279
+ description: 'Edit a file by searching for text and replacing it.',
280
+ category: 'core',
281
+ parameters: [
282
+ {
283
+ name: 'path',
284
+ type: 'string',
285
+ description: 'Path to the file to edit',
286
+ required: true,
287
+ },
288
+ {
289
+ name: 'search',
290
+ type: 'string',
291
+ description: 'Text to search for',
292
+ required: true,
293
+ },
294
+ {
295
+ name: 'replace',
296
+ type: 'string',
297
+ description: 'Replacement text',
298
+ required: true,
299
+ },
300
+ {
301
+ name: 'all',
302
+ type: 'boolean',
303
+ description: 'Replace all occurrences (default: first only)',
304
+ required: false,
305
+ default: false,
306
+ },
307
+ ],
308
+ returns: 'Success confirmation with replacement count',
309
+ },
310
+ async execute(params, context) {
311
+ const { path: filePath, search, replace, all = false } = params;
312
+ if (!filePath || !search) {
313
+ return { success: false, error: 'Path and search text are required' };
314
+ }
315
+ try {
316
+ const fullPath = path.resolve(context.workspaceDir || process.cwd(), filePath);
317
+ let content = await fs.readFile(fullPath, 'utf-8');
318
+ let count = 0;
319
+ if (all) {
320
+ const regex = new RegExp(search.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g');
321
+ count = (content.match(regex) || []).length;
322
+ content = content.replace(regex, replace);
323
+ }
324
+ else {
325
+ if (content.includes(search)) {
326
+ content = content.replace(search, replace);
327
+ count = 1;
328
+ }
329
+ }
330
+ await fs.writeFile(fullPath, content);
331
+ return {
332
+ success: true,
333
+ data: {
334
+ path: fullPath,
335
+ replacements: count,
336
+ },
337
+ };
338
+ }
339
+ catch (error) {
340
+ return { success: false, error: error.message };
341
+ }
342
+ },
343
+ };
344
+ exports.editFileTool = editFileTool;
345
+ // Register all file tools
346
+ function registerFileTools() {
347
+ index_1.toolRegistry.register(readFileTool);
348
+ index_1.toolRegistry.register(writeFileTool);
349
+ index_1.toolRegistry.register(listDirTool);
350
+ index_1.toolRegistry.register(deleteFileTool);
351
+ index_1.toolRegistry.register(editFileTool);
352
+ }
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ /**
3
+ * ApexBot Tools System
4
+ *
5
+ * Tools are capabilities that the agent can use to interact with the world.
6
+ * This is the core architecture for all integrations (like Clawdbot's skills).
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.toolRegistry = exports.ToolRegistry = void 0;
10
+ const events_1 = require("events");
11
+ class ToolRegistry extends events_1.EventEmitter {
12
+ tools = new Map();
13
+ categories = new Map();
14
+ register(tool) {
15
+ const name = tool.definition.name;
16
+ this.tools.set(name, tool);
17
+ // Track by category
18
+ const category = tool.definition.category;
19
+ if (!this.categories.has(category)) {
20
+ this.categories.set(category, new Set());
21
+ }
22
+ this.categories.get(category).add(name);
23
+ console.log(`[Tools] Registered: ${name} (${category})`);
24
+ this.emit('tool:registered', { name, category });
25
+ }
26
+ unregister(name) {
27
+ const tool = this.tools.get(name);
28
+ if (tool) {
29
+ this.tools.delete(name);
30
+ const category = tool.definition.category;
31
+ this.categories.get(category)?.delete(name);
32
+ console.log(`[Tools] Unregistered: ${name}`);
33
+ this.emit('tool:unregistered', { name });
34
+ }
35
+ }
36
+ get(name) {
37
+ return this.tools.get(name);
38
+ }
39
+ has(name) {
40
+ return this.tools.has(name);
41
+ }
42
+ list() {
43
+ return Array.from(this.tools.values()).map(t => t.definition);
44
+ }
45
+ listByCategory(category) {
46
+ const names = this.categories.get(category);
47
+ if (!names)
48
+ return [];
49
+ return Array.from(names)
50
+ .map(name => this.tools.get(name)?.definition)
51
+ .filter((d) => d !== undefined);
52
+ }
53
+ getCategories() {
54
+ return Array.from(this.categories.keys());
55
+ }
56
+ async execute(name, params, context) {
57
+ const tool = this.tools.get(name);
58
+ if (!tool) {
59
+ return { success: false, error: `Tool not found: ${name}` };
60
+ }
61
+ // Validate parameters
62
+ if (tool.validate && !tool.validate(params)) {
63
+ return { success: false, error: `Invalid parameters for tool: ${name}` };
64
+ }
65
+ try {
66
+ console.log(`[Tools] Executing: ${name}`);
67
+ this.emit('tool:executing', { name, params });
68
+ const result = await tool.execute(params, context);
69
+ this.emit('tool:executed', { name, params, result });
70
+ console.log(`[Tools] Completed: ${name} (success: ${result.success})`);
71
+ return result;
72
+ }
73
+ catch (error) {
74
+ console.error(`[Tools] Error executing ${name}:`, error);
75
+ return { success: false, error: error.message || 'Unknown error' };
76
+ }
77
+ }
78
+ // Generate OpenAI/Anthropic function calling schema
79
+ toFunctionSchema() {
80
+ return Array.from(this.tools.values()).map(tool => ({
81
+ type: 'function',
82
+ function: {
83
+ name: tool.definition.name,
84
+ description: tool.definition.description,
85
+ parameters: {
86
+ type: 'object',
87
+ properties: tool.definition.parameters.reduce((acc, param) => {
88
+ acc[param.name] = {
89
+ type: param.type,
90
+ description: param.description,
91
+ ...(param.enum ? { enum: param.enum } : {}),
92
+ ...(param.default !== undefined ? { default: param.default } : {}),
93
+ };
94
+ return acc;
95
+ }, {}),
96
+ required: tool.definition.parameters
97
+ .filter(p => p.required)
98
+ .map(p => p.name),
99
+ },
100
+ },
101
+ }));
102
+ }
103
+ // Generate Ollama tools schema
104
+ toOllamaSchema() {
105
+ return this.toFunctionSchema();
106
+ }
107
+ }
108
+ exports.ToolRegistry = ToolRegistry;
109
+ // Global registry instance
110
+ exports.toolRegistry = new ToolRegistry();
111
+ exports.default = exports.toolRegistry;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ /**
3
+ * Tools & Skills Loader
4
+ *
5
+ * Registers all built-in tools and skills.
6
+ */
7
+ var __importDefault = (this && this.__importDefault) || function (mod) {
8
+ return (mod && mod.__esModule) ? mod : { "default": mod };
9
+ };
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.toolRegistry = void 0;
12
+ exports.registerBuiltInTools = registerBuiltInTools;
13
+ exports.registerSkills = registerSkills;
14
+ exports.initializeToolsSystem = initializeToolsSystem;
15
+ const tools_1 = require("../tools");
16
+ Object.defineProperty(exports, "toolRegistry", { enumerable: true, get: function () { return tools_1.toolRegistry; } });
17
+ const shell_1 = __importDefault(require("../tools/shell"));
18
+ const file_1 = require("../tools/file");
19
+ const web_1 = require("../tools/web");
20
+ const datetime_1 = require("../tools/datetime");
21
+ const math_1 = require("../tools/math");
22
+ const skills_1 = require("../skills");
23
+ const obsidian_1 = __importDefault(require("../skills/obsidian"));
24
+ const weather_1 = __importDefault(require("../skills/weather"));
25
+ const reminder_1 = __importDefault(require("../skills/reminder"));
26
+ const system_1 = __importDefault(require("../skills/system"));
27
+ /**
28
+ * Register all built-in tools
29
+ */
30
+ function registerBuiltInTools() {
31
+ console.log('[Loader] Registering built-in tools...');
32
+ // Core tools
33
+ tools_1.toolRegistry.register(shell_1.default);
34
+ (0, file_1.registerFileTools)();
35
+ (0, web_1.registerWebTools)();
36
+ (0, datetime_1.registerDateTimeTools)();
37
+ (0, math_1.registerMathTools)();
38
+ console.log(`[Loader] Registered ${tools_1.toolRegistry.list().length} tools`);
39
+ }
40
+ /**
41
+ * Register all built-in skills and load user configuration
42
+ */
43
+ async function registerSkills(configDir) {
44
+ console.log('[Loader] Registering skills...');
45
+ const skillManager = (0, skills_1.initSkillManager)(configDir);
46
+ await skillManager.loadConfig();
47
+ // Register built-in skills
48
+ skillManager.register(obsidian_1.default);
49
+ skillManager.register(weather_1.default);
50
+ skillManager.register(reminder_1.default);
51
+ skillManager.register(system_1.default);
52
+ // Initialize enabled skills
53
+ await skillManager.initializeEnabled();
54
+ console.log(`[Loader] Registered ${skillManager.list().length} skills`);
55
+ return skillManager;
56
+ }
57
+ /**
58
+ * Initialize the entire tools system
59
+ */
60
+ async function initializeToolsSystem(configDir) {
61
+ registerBuiltInTools();
62
+ const skillManager = await registerSkills(configDir);
63
+ console.log('[Loader] Tools system ready');
64
+ console.log('[Loader] Available tools:', tools_1.toolRegistry.list().map(t => t.name).join(', '));
65
+ return skillManager;
66
+ }