codebot-ai 1.0.0
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/LICENSE +21 -0
- package/README.md +247 -0
- package/bin/codebot +5 -0
- package/dist/agent.d.ts +31 -0
- package/dist/agent.js +256 -0
- package/dist/banner.d.ts +19 -0
- package/dist/banner.js +148 -0
- package/dist/browser/cdp.d.ts +29 -0
- package/dist/browser/cdp.js +292 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +518 -0
- package/dist/context/manager.d.ts +27 -0
- package/dist/context/manager.js +139 -0
- package/dist/context/repo-map.d.ts +5 -0
- package/dist/context/repo-map.js +100 -0
- package/dist/history.d.ts +27 -0
- package/dist/history.js +146 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +42 -0
- package/dist/memory.d.ts +39 -0
- package/dist/memory.js +168 -0
- package/dist/parser.d.ts +8 -0
- package/dist/parser.js +79 -0
- package/dist/providers/anthropic.d.ts +9 -0
- package/dist/providers/anthropic.js +288 -0
- package/dist/providers/index.d.ts +5 -0
- package/dist/providers/index.js +13 -0
- package/dist/providers/openai.d.ts +11 -0
- package/dist/providers/openai.js +173 -0
- package/dist/providers/registry.d.ts +15 -0
- package/dist/providers/registry.js +115 -0
- package/dist/setup.d.ts +17 -0
- package/dist/setup.js +243 -0
- package/dist/tools/browser.d.ts +43 -0
- package/dist/tools/browser.js +329 -0
- package/dist/tools/edit.d.ts +26 -0
- package/dist/tools/edit.js +73 -0
- package/dist/tools/execute.d.ts +26 -0
- package/dist/tools/execute.js +52 -0
- package/dist/tools/glob.d.ts +24 -0
- package/dist/tools/glob.js +102 -0
- package/dist/tools/grep.d.ts +29 -0
- package/dist/tools/grep.js +125 -0
- package/dist/tools/index.d.ts +10 -0
- package/dist/tools/index.js +49 -0
- package/dist/tools/memory.d.ts +36 -0
- package/dist/tools/memory.js +114 -0
- package/dist/tools/read.d.ts +26 -0
- package/dist/tools/read.js +75 -0
- package/dist/tools/think.d.ts +18 -0
- package/dist/tools/think.js +20 -0
- package/dist/tools/web-fetch.d.ts +36 -0
- package/dist/tools/web-fetch.js +83 -0
- package/dist/tools/write.d.ts +22 -0
- package/dist/tools/write.js +65 -0
- package/dist/types.d.ts +82 -0
- package/dist/types.js +3 -0
- package/package.json +57 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.EditFileTool = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
class EditFileTool {
|
|
40
|
+
name = 'edit_file';
|
|
41
|
+
description = 'Edit a file by replacing an exact string match with new content. The old_string must appear exactly once in the file.';
|
|
42
|
+
permission = 'prompt';
|
|
43
|
+
parameters = {
|
|
44
|
+
type: 'object',
|
|
45
|
+
properties: {
|
|
46
|
+
path: { type: 'string', description: 'Path to the file to edit' },
|
|
47
|
+
old_string: { type: 'string', description: 'Exact string to find (must be unique in the file)' },
|
|
48
|
+
new_string: { type: 'string', description: 'Replacement string' },
|
|
49
|
+
},
|
|
50
|
+
required: ['path', 'old_string', 'new_string'],
|
|
51
|
+
};
|
|
52
|
+
async execute(args) {
|
|
53
|
+
const filePath = path.resolve(args.path);
|
|
54
|
+
const oldStr = args.old_string;
|
|
55
|
+
const newStr = args.new_string;
|
|
56
|
+
if (!fs.existsSync(filePath)) {
|
|
57
|
+
throw new Error(`File not found: ${filePath}`);
|
|
58
|
+
}
|
|
59
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
60
|
+
const count = content.split(oldStr).length - 1;
|
|
61
|
+
if (count === 0) {
|
|
62
|
+
throw new Error(`String not found in ${filePath}. Make sure old_string matches exactly (including whitespace).`);
|
|
63
|
+
}
|
|
64
|
+
if (count > 1) {
|
|
65
|
+
throw new Error(`String found ${count} times in ${filePath}. Provide more surrounding context to make it unique.`);
|
|
66
|
+
}
|
|
67
|
+
const updated = content.replace(oldStr, newStr);
|
|
68
|
+
fs.writeFileSync(filePath, updated, 'utf-8');
|
|
69
|
+
return `Edited ${filePath} (1 replacement)`;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.EditFileTool = EditFileTool;
|
|
73
|
+
//# sourceMappingURL=edit.js.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Tool } from '../types';
|
|
2
|
+
export declare class ExecuteTool implements Tool {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
permission: Tool['permission'];
|
|
6
|
+
parameters: {
|
|
7
|
+
type: string;
|
|
8
|
+
properties: {
|
|
9
|
+
command: {
|
|
10
|
+
type: string;
|
|
11
|
+
description: string;
|
|
12
|
+
};
|
|
13
|
+
cwd: {
|
|
14
|
+
type: string;
|
|
15
|
+
description: string;
|
|
16
|
+
};
|
|
17
|
+
timeout: {
|
|
18
|
+
type: string;
|
|
19
|
+
description: string;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
required: string[];
|
|
23
|
+
};
|
|
24
|
+
execute(args: Record<string, unknown>): Promise<string>;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=execute.d.ts.map
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ExecuteTool = void 0;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const BLOCKED_PATTERNS = [
|
|
6
|
+
/rm\s+-rf\s+\//,
|
|
7
|
+
/rm\s+-rf\s+~/,
|
|
8
|
+
/rm\s+-rf\s+\*/,
|
|
9
|
+
/mkfs\./,
|
|
10
|
+
/dd\s+if=.*of=\/dev\//,
|
|
11
|
+
/:\(\)\s*\{[^}]*:\|:.*\}/,
|
|
12
|
+
/chmod\s+-R\s+777\s+\//,
|
|
13
|
+
/format\s+c:/i,
|
|
14
|
+
];
|
|
15
|
+
class ExecuteTool {
|
|
16
|
+
name = 'execute';
|
|
17
|
+
description = 'Execute a shell command. Returns stdout and stderr. Use for running tests, builds, git commands, etc.';
|
|
18
|
+
permission = 'always-ask';
|
|
19
|
+
parameters = {
|
|
20
|
+
type: 'object',
|
|
21
|
+
properties: {
|
|
22
|
+
command: { type: 'string', description: 'Shell command to execute' },
|
|
23
|
+
cwd: { type: 'string', description: 'Working directory (defaults to current)' },
|
|
24
|
+
timeout: { type: 'number', description: 'Timeout in ms (default: 30000)' },
|
|
25
|
+
},
|
|
26
|
+
required: ['command'],
|
|
27
|
+
};
|
|
28
|
+
async execute(args) {
|
|
29
|
+
const cmd = args.command;
|
|
30
|
+
for (const pattern of BLOCKED_PATTERNS) {
|
|
31
|
+
if (pattern.test(cmd)) {
|
|
32
|
+
throw new Error(`Blocked: "${cmd}" matches a dangerous command pattern.`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
const output = (0, child_process_1.execSync)(cmd, {
|
|
37
|
+
cwd: args.cwd || process.cwd(),
|
|
38
|
+
timeout: args.timeout || 30000,
|
|
39
|
+
maxBuffer: 1024 * 1024,
|
|
40
|
+
encoding: 'utf-8',
|
|
41
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
42
|
+
});
|
|
43
|
+
return output || '(no output)';
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
const e = err;
|
|
47
|
+
return `Exit code ${e.status || 1}\nSTDOUT:\n${e.stdout || ''}\nSTDERR:\n${e.stderr || ''}`;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.ExecuteTool = ExecuteTool;
|
|
52
|
+
//# sourceMappingURL=execute.js.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Tool } from '../types';
|
|
2
|
+
export declare class GlobTool implements Tool {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
permission: Tool['permission'];
|
|
6
|
+
parameters: {
|
|
7
|
+
type: string;
|
|
8
|
+
properties: {
|
|
9
|
+
pattern: {
|
|
10
|
+
type: string;
|
|
11
|
+
description: string;
|
|
12
|
+
};
|
|
13
|
+
cwd: {
|
|
14
|
+
type: string;
|
|
15
|
+
description: string;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
required: string[];
|
|
19
|
+
};
|
|
20
|
+
execute(args: Record<string, unknown>): Promise<string>;
|
|
21
|
+
private walkAndMatch;
|
|
22
|
+
private patternToRegex;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=glob.d.ts.map
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.GlobTool = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
class GlobTool {
|
|
40
|
+
name = 'glob';
|
|
41
|
+
description = 'Find files matching a glob pattern. Returns matching file paths relative to the search directory.';
|
|
42
|
+
permission = 'auto';
|
|
43
|
+
parameters = {
|
|
44
|
+
type: 'object',
|
|
45
|
+
properties: {
|
|
46
|
+
pattern: { type: 'string', description: 'Glob pattern (e.g., "**/*.ts", "src/**/*.js")' },
|
|
47
|
+
cwd: { type: 'string', description: 'Directory to search in (defaults to current)' },
|
|
48
|
+
},
|
|
49
|
+
required: ['pattern'],
|
|
50
|
+
};
|
|
51
|
+
async execute(args) {
|
|
52
|
+
const cwd = args.cwd || process.cwd();
|
|
53
|
+
const pattern = args.pattern;
|
|
54
|
+
const matches = this.walkAndMatch(cwd, pattern);
|
|
55
|
+
if (matches.length === 0)
|
|
56
|
+
return 'No files found matching pattern.';
|
|
57
|
+
if (matches.length > 100) {
|
|
58
|
+
return `${matches.slice(0, 100).join('\n')}\n\n... and ${matches.length - 100} more files`;
|
|
59
|
+
}
|
|
60
|
+
return matches.join('\n');
|
|
61
|
+
}
|
|
62
|
+
walkAndMatch(dir, pattern) {
|
|
63
|
+
const results = [];
|
|
64
|
+
const regex = this.patternToRegex(pattern);
|
|
65
|
+
const skip = new Set(['node_modules', '.git', 'dist', 'build', 'coverage', '__pycache__', '.next']);
|
|
66
|
+
const walk = (currentDir, rel) => {
|
|
67
|
+
let entries;
|
|
68
|
+
try {
|
|
69
|
+
entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
for (const entry of entries) {
|
|
75
|
+
if (entry.name.startsWith('.') && !pattern.startsWith('.'))
|
|
76
|
+
continue;
|
|
77
|
+
if (skip.has(entry.name))
|
|
78
|
+
continue;
|
|
79
|
+
const relPath = rel ? `${rel}/${entry.name}` : entry.name;
|
|
80
|
+
if (entry.isDirectory()) {
|
|
81
|
+
walk(path.join(currentDir, entry.name), relPath);
|
|
82
|
+
}
|
|
83
|
+
else if (regex.test(relPath)) {
|
|
84
|
+
results.push(relPath);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
walk(dir, '');
|
|
89
|
+
return results.sort();
|
|
90
|
+
}
|
|
91
|
+
patternToRegex(pattern) {
|
|
92
|
+
const regex = pattern
|
|
93
|
+
.replace(/[.+^${}()|[\]\\]/g, '\\$&')
|
|
94
|
+
.replace(/\*\*/g, '{{GLOBSTAR}}')
|
|
95
|
+
.replace(/\*/g, '[^/]*')
|
|
96
|
+
.replace(/\{\{GLOBSTAR\}\}/g, '.*')
|
|
97
|
+
.replace(/\?/g, '[^/]');
|
|
98
|
+
return new RegExp(`^${regex}$`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
exports.GlobTool = GlobTool;
|
|
102
|
+
//# sourceMappingURL=glob.js.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Tool } from '../types';
|
|
2
|
+
export declare class GrepTool implements Tool {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
permission: Tool['permission'];
|
|
6
|
+
parameters: {
|
|
7
|
+
type: string;
|
|
8
|
+
properties: {
|
|
9
|
+
pattern: {
|
|
10
|
+
type: string;
|
|
11
|
+
description: string;
|
|
12
|
+
};
|
|
13
|
+
path: {
|
|
14
|
+
type: string;
|
|
15
|
+
description: string;
|
|
16
|
+
};
|
|
17
|
+
include: {
|
|
18
|
+
type: string;
|
|
19
|
+
description: string;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
required: string[];
|
|
23
|
+
};
|
|
24
|
+
execute(args: Record<string, unknown>): Promise<string>;
|
|
25
|
+
private searchFile;
|
|
26
|
+
private searchDir;
|
|
27
|
+
private globToRegex;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=grep.d.ts.map
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.GrepTool = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
class GrepTool {
|
|
40
|
+
name = 'grep';
|
|
41
|
+
description = 'Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.';
|
|
42
|
+
permission = 'auto';
|
|
43
|
+
parameters = {
|
|
44
|
+
type: 'object',
|
|
45
|
+
properties: {
|
|
46
|
+
pattern: { type: 'string', description: 'Regex pattern to search for' },
|
|
47
|
+
path: { type: 'string', description: 'File or directory to search (defaults to current directory)' },
|
|
48
|
+
include: { type: 'string', description: 'File extension filter (e.g., "*.ts", "*.js")' },
|
|
49
|
+
},
|
|
50
|
+
required: ['pattern'],
|
|
51
|
+
};
|
|
52
|
+
async execute(args) {
|
|
53
|
+
const searchPath = args.path || process.cwd();
|
|
54
|
+
const regex = new RegExp(args.pattern, 'gi');
|
|
55
|
+
const results = [];
|
|
56
|
+
const maxResults = 50;
|
|
57
|
+
const stat = fs.statSync(searchPath);
|
|
58
|
+
if (stat.isFile()) {
|
|
59
|
+
this.searchFile(searchPath, regex, results, maxResults);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
this.searchDir(searchPath, regex, results, args.include, maxResults);
|
|
63
|
+
}
|
|
64
|
+
if (results.length === 0)
|
|
65
|
+
return 'No matches found.';
|
|
66
|
+
const header = results.length >= maxResults ? `(showing first ${maxResults} matches)\n` : '';
|
|
67
|
+
return header + results.join('\n');
|
|
68
|
+
}
|
|
69
|
+
searchFile(filePath, regex, results, maxResults) {
|
|
70
|
+
if (results.length >= maxResults)
|
|
71
|
+
return;
|
|
72
|
+
try {
|
|
73
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
74
|
+
if (content.includes('\0'))
|
|
75
|
+
return; // skip binary files
|
|
76
|
+
const lines = content.split('\n');
|
|
77
|
+
for (let i = 0; i < lines.length && results.length < maxResults; i++) {
|
|
78
|
+
regex.lastIndex = 0;
|
|
79
|
+
if (regex.test(lines[i])) {
|
|
80
|
+
results.push(`${filePath}:${i + 1}: ${lines[i].trimEnd()}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// skip unreadable files
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
searchDir(dir, regex, results, include, maxResults) {
|
|
89
|
+
if (results.length >= maxResults)
|
|
90
|
+
return;
|
|
91
|
+
const skip = new Set(['node_modules', '.git', 'dist', 'build', 'coverage', '__pycache__']);
|
|
92
|
+
let entries;
|
|
93
|
+
try {
|
|
94
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const includeRegex = include ? this.globToRegex(include) : null;
|
|
100
|
+
for (const entry of entries) {
|
|
101
|
+
if (results.length >= maxResults)
|
|
102
|
+
break;
|
|
103
|
+
if (entry.name.startsWith('.') || skip.has(entry.name))
|
|
104
|
+
continue;
|
|
105
|
+
const fullPath = path.join(dir, entry.name);
|
|
106
|
+
if (entry.isDirectory()) {
|
|
107
|
+
this.searchDir(fullPath, regex, results, include, maxResults);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
if (includeRegex && !includeRegex.test(entry.name))
|
|
111
|
+
continue;
|
|
112
|
+
this.searchFile(fullPath, regex, results, maxResults);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
globToRegex(glob) {
|
|
117
|
+
const regex = glob
|
|
118
|
+
.replace(/[.+^${}()|[\]\\]/g, '\\$&')
|
|
119
|
+
.replace(/\*/g, '.*')
|
|
120
|
+
.replace(/\?/g, '.');
|
|
121
|
+
return new RegExp(`^${regex}$`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
exports.GrepTool = GrepTool;
|
|
125
|
+
//# sourceMappingURL=grep.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Tool, ToolSchema } from '../types';
|
|
2
|
+
export declare class ToolRegistry {
|
|
3
|
+
private tools;
|
|
4
|
+
constructor(projectRoot?: string);
|
|
5
|
+
register(tool: Tool): void;
|
|
6
|
+
get(name: string): Tool | undefined;
|
|
7
|
+
getSchemas(): ToolSchema[];
|
|
8
|
+
all(): Tool[];
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ToolRegistry = void 0;
|
|
4
|
+
const read_1 = require("./read");
|
|
5
|
+
const write_1 = require("./write");
|
|
6
|
+
const edit_1 = require("./edit");
|
|
7
|
+
const execute_1 = require("./execute");
|
|
8
|
+
const glob_1 = require("./glob");
|
|
9
|
+
const grep_1 = require("./grep");
|
|
10
|
+
const think_1 = require("./think");
|
|
11
|
+
const memory_1 = require("./memory");
|
|
12
|
+
const web_fetch_1 = require("./web-fetch");
|
|
13
|
+
const browser_1 = require("./browser");
|
|
14
|
+
class ToolRegistry {
|
|
15
|
+
tools = new Map();
|
|
16
|
+
constructor(projectRoot) {
|
|
17
|
+
this.register(new read_1.ReadFileTool());
|
|
18
|
+
this.register(new write_1.WriteFileTool());
|
|
19
|
+
this.register(new edit_1.EditFileTool());
|
|
20
|
+
this.register(new execute_1.ExecuteTool());
|
|
21
|
+
this.register(new glob_1.GlobTool());
|
|
22
|
+
this.register(new grep_1.GrepTool());
|
|
23
|
+
this.register(new think_1.ThinkTool());
|
|
24
|
+
this.register(new memory_1.MemoryTool(projectRoot));
|
|
25
|
+
this.register(new web_fetch_1.WebFetchTool());
|
|
26
|
+
this.register(new browser_1.BrowserTool());
|
|
27
|
+
}
|
|
28
|
+
register(tool) {
|
|
29
|
+
this.tools.set(tool.name, tool);
|
|
30
|
+
}
|
|
31
|
+
get(name) {
|
|
32
|
+
return this.tools.get(name);
|
|
33
|
+
}
|
|
34
|
+
getSchemas() {
|
|
35
|
+
return Array.from(this.tools.values()).map(t => ({
|
|
36
|
+
type: 'function',
|
|
37
|
+
function: {
|
|
38
|
+
name: t.name,
|
|
39
|
+
description: t.description,
|
|
40
|
+
parameters: t.parameters,
|
|
41
|
+
},
|
|
42
|
+
}));
|
|
43
|
+
}
|
|
44
|
+
all() {
|
|
45
|
+
return Array.from(this.tools.values());
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.ToolRegistry = ToolRegistry;
|
|
49
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Tool } from '../types';
|
|
2
|
+
export declare class MemoryTool implements Tool {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
permission: Tool['permission'];
|
|
6
|
+
parameters: {
|
|
7
|
+
type: string;
|
|
8
|
+
properties: {
|
|
9
|
+
action: {
|
|
10
|
+
type: string;
|
|
11
|
+
description: string;
|
|
12
|
+
enum: string[];
|
|
13
|
+
};
|
|
14
|
+
scope: {
|
|
15
|
+
type: string;
|
|
16
|
+
description: string;
|
|
17
|
+
enum: string[];
|
|
18
|
+
};
|
|
19
|
+
content: {
|
|
20
|
+
type: string;
|
|
21
|
+
description: string;
|
|
22
|
+
};
|
|
23
|
+
file: {
|
|
24
|
+
type: string;
|
|
25
|
+
description: string;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
required: string[];
|
|
29
|
+
};
|
|
30
|
+
private memory;
|
|
31
|
+
constructor(projectRoot?: string);
|
|
32
|
+
execute(args: Record<string, unknown>): Promise<string>;
|
|
33
|
+
private readTopicFile;
|
|
34
|
+
private writeTopicFile;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=memory.d.ts.map
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MemoryTool = void 0;
|
|
4
|
+
const memory_1 = require("../memory");
|
|
5
|
+
class MemoryTool {
|
|
6
|
+
name = 'memory';
|
|
7
|
+
description = 'Read or write persistent memory. Memory survives across sessions and is always available to you. Use this to remember important context, user preferences, project patterns, or anything worth keeping.';
|
|
8
|
+
permission = 'auto';
|
|
9
|
+
parameters = {
|
|
10
|
+
type: 'object',
|
|
11
|
+
properties: {
|
|
12
|
+
action: {
|
|
13
|
+
type: 'string',
|
|
14
|
+
description: 'Action: "read" to view memory, "write" to add/update, "list" to show all files',
|
|
15
|
+
enum: ['read', 'write', 'list'],
|
|
16
|
+
},
|
|
17
|
+
scope: {
|
|
18
|
+
type: 'string',
|
|
19
|
+
description: 'Scope: "global" for all projects, "project" for current project',
|
|
20
|
+
enum: ['global', 'project'],
|
|
21
|
+
},
|
|
22
|
+
content: {
|
|
23
|
+
type: 'string',
|
|
24
|
+
description: 'Content to write (for write action)',
|
|
25
|
+
},
|
|
26
|
+
file: {
|
|
27
|
+
type: 'string',
|
|
28
|
+
description: 'Topic file name (e.g., "patterns" creates patterns.md). Omit for main MEMORY.md',
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
required: ['action'],
|
|
32
|
+
};
|
|
33
|
+
memory;
|
|
34
|
+
constructor(projectRoot) {
|
|
35
|
+
this.memory = new memory_1.MemoryManager(projectRoot);
|
|
36
|
+
}
|
|
37
|
+
async execute(args) {
|
|
38
|
+
const action = args.action;
|
|
39
|
+
const scope = args.scope || 'project';
|
|
40
|
+
const content = args.content;
|
|
41
|
+
const file = args.file;
|
|
42
|
+
switch (action) {
|
|
43
|
+
case 'read': {
|
|
44
|
+
if (file) {
|
|
45
|
+
return this.readTopicFile(scope, file);
|
|
46
|
+
}
|
|
47
|
+
const result = scope === 'global'
|
|
48
|
+
? this.memory.readGlobal()
|
|
49
|
+
: this.memory.readProject();
|
|
50
|
+
return result || '(empty — no memory saved yet)';
|
|
51
|
+
}
|
|
52
|
+
case 'write': {
|
|
53
|
+
if (!content)
|
|
54
|
+
return 'Error: content is required for write action';
|
|
55
|
+
if (file) {
|
|
56
|
+
return this.writeTopicFile(scope, file, content);
|
|
57
|
+
}
|
|
58
|
+
if (scope === 'global') {
|
|
59
|
+
this.memory.appendGlobal(content);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
this.memory.appendProject(content);
|
|
63
|
+
}
|
|
64
|
+
return `Memory updated (${scope}).`;
|
|
65
|
+
}
|
|
66
|
+
case 'list': {
|
|
67
|
+
const files = this.memory.list();
|
|
68
|
+
if (files.length === 0)
|
|
69
|
+
return 'No memory files yet.';
|
|
70
|
+
return files
|
|
71
|
+
.map(f => `[${f.scope}] ${f.file} (${f.size} bytes)`)
|
|
72
|
+
.join('\n');
|
|
73
|
+
}
|
|
74
|
+
default:
|
|
75
|
+
return `Error: Unknown action "${action}". Use read, write, or list.`;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
readTopicFile(scope, file) {
|
|
79
|
+
const fs = require('fs');
|
|
80
|
+
const path = require('path');
|
|
81
|
+
const os = require('os');
|
|
82
|
+
const fileName = file.endsWith('.md') ? file : `${file}.md`;
|
|
83
|
+
let dir;
|
|
84
|
+
if (scope === 'global') {
|
|
85
|
+
dir = path.join(os.homedir(), '.codebot', 'memory');
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
dir = path.join(process.cwd(), '.codebot', 'memory');
|
|
89
|
+
}
|
|
90
|
+
const filePath = path.join(dir, fileName);
|
|
91
|
+
if (fs.existsSync(filePath)) {
|
|
92
|
+
return fs.readFileSync(filePath, 'utf-8');
|
|
93
|
+
}
|
|
94
|
+
return `(no file: ${fileName})`;
|
|
95
|
+
}
|
|
96
|
+
writeTopicFile(scope, file, content) {
|
|
97
|
+
const fs = require('fs');
|
|
98
|
+
const path = require('path');
|
|
99
|
+
const os = require('os');
|
|
100
|
+
const fileName = file.endsWith('.md') ? file : `${file}.md`;
|
|
101
|
+
let dir;
|
|
102
|
+
if (scope === 'global') {
|
|
103
|
+
dir = path.join(os.homedir(), '.codebot', 'memory');
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
dir = path.join(process.cwd(), '.codebot', 'memory');
|
|
107
|
+
}
|
|
108
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
109
|
+
fs.writeFileSync(path.join(dir, fileName), content);
|
|
110
|
+
return `Wrote ${fileName} (${scope}).`;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
exports.MemoryTool = MemoryTool;
|
|
114
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Tool } from '../types';
|
|
2
|
+
export declare class ReadFileTool implements Tool {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
permission: Tool['permission'];
|
|
6
|
+
parameters: {
|
|
7
|
+
type: string;
|
|
8
|
+
properties: {
|
|
9
|
+
path: {
|
|
10
|
+
type: string;
|
|
11
|
+
description: string;
|
|
12
|
+
};
|
|
13
|
+
offset: {
|
|
14
|
+
type: string;
|
|
15
|
+
description: string;
|
|
16
|
+
};
|
|
17
|
+
limit: {
|
|
18
|
+
type: string;
|
|
19
|
+
description: string;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
required: string[];
|
|
23
|
+
};
|
|
24
|
+
execute(args: Record<string, unknown>): Promise<string>;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=read.d.ts.map
|