codebot-ai 1.3.0 → 1.4.1

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.
Files changed (40) hide show
  1. package/README.md +16 -1
  2. package/dist/agent.js +23 -1
  3. package/dist/cli.js +1 -1
  4. package/dist/providers/anthropic.js +27 -1
  5. package/dist/providers/openai.d.ts +4 -0
  6. package/dist/providers/openai.js +54 -2
  7. package/dist/retry.d.ts +5 -0
  8. package/dist/retry.js +24 -0
  9. package/dist/tools/code-analysis.d.ts +33 -0
  10. package/dist/tools/code-analysis.js +232 -0
  11. package/dist/tools/code-review.d.ts +32 -0
  12. package/dist/tools/code-review.js +228 -0
  13. package/dist/tools/database.d.ts +35 -0
  14. package/dist/tools/database.js +129 -0
  15. package/dist/tools/diff-viewer.d.ts +39 -0
  16. package/dist/tools/diff-viewer.js +145 -0
  17. package/dist/tools/docker.d.ts +26 -0
  18. package/dist/tools/docker.js +101 -0
  19. package/dist/tools/git.d.ts +26 -0
  20. package/dist/tools/git.js +58 -0
  21. package/dist/tools/http-client.d.ts +39 -0
  22. package/dist/tools/http-client.js +114 -0
  23. package/dist/tools/image-info.d.ts +23 -0
  24. package/dist/tools/image-info.js +170 -0
  25. package/dist/tools/index.js +34 -0
  26. package/dist/tools/multi-search.d.ts +28 -0
  27. package/dist/tools/multi-search.js +153 -0
  28. package/dist/tools/notification.d.ts +38 -0
  29. package/dist/tools/notification.js +96 -0
  30. package/dist/tools/package-manager.d.ts +31 -0
  31. package/dist/tools/package-manager.js +161 -0
  32. package/dist/tools/pdf-extract.d.ts +33 -0
  33. package/dist/tools/pdf-extract.js +178 -0
  34. package/dist/tools/ssh-remote.d.ts +39 -0
  35. package/dist/tools/ssh-remote.js +84 -0
  36. package/dist/tools/task-planner.d.ts +42 -0
  37. package/dist/tools/task-planner.js +161 -0
  38. package/dist/tools/test-runner.d.ts +36 -0
  39. package/dist/tools/test-runner.js +193 -0
  40. package/package.json +1 -1
@@ -0,0 +1,153 @@
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.MultiSearchTool = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ class MultiSearchTool {
40
+ name = 'multi_search';
41
+ description = 'Fuzzy search across filenames, file contents, and code symbols. Returns ranked results by relevance.';
42
+ permission = 'auto';
43
+ parameters = {
44
+ type: 'object',
45
+ properties: {
46
+ query: { type: 'string', description: 'Search query (fuzzy matched against filenames, content, and symbols)' },
47
+ path: { type: 'string', description: 'Directory to search (defaults to current)' },
48
+ max_results: { type: 'number', description: 'Max results to return (default: 20)' },
49
+ },
50
+ required: ['query'],
51
+ };
52
+ async execute(args) {
53
+ const query = args.query;
54
+ if (!query)
55
+ return 'Error: query is required';
56
+ const searchPath = args.path || process.cwd();
57
+ const maxResults = args.max_results || 20;
58
+ if (!fs.existsSync(searchPath))
59
+ return `Error: path not found: ${searchPath}`;
60
+ const results = [];
61
+ const queryLower = query.toLowerCase();
62
+ const queryParts = queryLower.split(/\s+/);
63
+ this.searchDir(searchPath, queryLower, queryParts, results);
64
+ // Sort by score descending
65
+ results.sort((a, b) => b.score - a.score);
66
+ const top = results.slice(0, maxResults);
67
+ if (top.length === 0)
68
+ return `No results for "${query}".`;
69
+ const lines = top.map(r => {
70
+ const tag = r.type === 'filename' ? '[file]' : r.type === 'symbol' ? '[symbol]' : '[content]';
71
+ const loc = r.line ? `:${r.line}` : '';
72
+ const preview = r.text ? ` — ${r.text.substring(0, 80)}` : '';
73
+ return ` ${tag} ${r.file}${loc}${preview}`;
74
+ });
75
+ return `Search results for "${query}" (${top.length} matches):\n${lines.join('\n')}`;
76
+ }
77
+ searchDir(dir, query, parts, results) {
78
+ const skip = new Set(['node_modules', '.git', 'dist', 'build', 'coverage', '__pycache__', '.next']);
79
+ const codeExts = new Set(['.ts', '.js', '.tsx', '.jsx', '.py', '.go', '.rs', '.java', '.rb', '.c', '.cpp', '.h', '.css', '.html', '.json', '.md', '.yaml', '.yml', '.toml']);
80
+ let entries;
81
+ try {
82
+ entries = fs.readdirSync(dir, { withFileTypes: true });
83
+ }
84
+ catch {
85
+ return;
86
+ }
87
+ for (const entry of entries) {
88
+ if (entry.name.startsWith('.') || skip.has(entry.name))
89
+ continue;
90
+ const full = path.join(dir, entry.name);
91
+ if (entry.isDirectory()) {
92
+ // Score directory name
93
+ const dirScore = this.fuzzyScore(entry.name.toLowerCase(), query, parts);
94
+ if (dirScore > 0) {
95
+ results.push({ file: full + '/', score: dirScore * 0.5, type: 'filename' });
96
+ }
97
+ this.searchDir(full, query, parts, results);
98
+ }
99
+ else {
100
+ // Filename match
101
+ const nameScore = this.fuzzyScore(entry.name.toLowerCase(), query, parts);
102
+ if (nameScore > 0) {
103
+ results.push({ file: full, score: nameScore, type: 'filename' });
104
+ }
105
+ // Content + symbol search for code files
106
+ const ext = path.extname(entry.name).toLowerCase();
107
+ if (!codeExts.has(ext))
108
+ continue;
109
+ try {
110
+ const content = fs.readFileSync(full, 'utf-8');
111
+ if (content.length > 500_000 || content.includes('\0'))
112
+ continue; // skip huge/binary
113
+ const lines = content.split('\n');
114
+ for (let i = 0; i < lines.length; i++) {
115
+ const line = lines[i];
116
+ const lineLower = line.toLowerCase();
117
+ // Content match
118
+ if (lineLower.includes(query)) {
119
+ results.push({ file: full, line: i + 1, text: line.trimEnd(), score: 3, type: 'content' });
120
+ }
121
+ // Symbol match (class, function, method definitions)
122
+ const symbolMatch = line.match(/(?:class|function|interface|type|const|let|var|def|fn|func)\s+(\w+)/);
123
+ if (symbolMatch) {
124
+ const symScore = this.fuzzyScore(symbolMatch[1].toLowerCase(), query, parts);
125
+ if (symScore > 0) {
126
+ results.push({ file: full, line: i + 1, text: line.trimEnd(), score: symScore * 1.5, type: 'symbol' });
127
+ }
128
+ }
129
+ }
130
+ }
131
+ catch { /* skip */ }
132
+ }
133
+ }
134
+ }
135
+ fuzzyScore(target, query, parts) {
136
+ // Exact match
137
+ if (target === query)
138
+ return 10;
139
+ // Contains full query
140
+ if (target.includes(query))
141
+ return 7;
142
+ // All parts present
143
+ if (parts.every(p => target.includes(p)))
144
+ return 5;
145
+ // Some parts present
146
+ const matched = parts.filter(p => target.includes(p)).length;
147
+ if (matched > 0)
148
+ return matched * 2;
149
+ return 0;
150
+ }
151
+ }
152
+ exports.MultiSearchTool = MultiSearchTool;
153
+ //# sourceMappingURL=multi-search.js.map
@@ -0,0 +1,38 @@
1
+ import { Tool } from '../types';
2
+ export declare class NotificationTool 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
+ };
13
+ url: {
14
+ type: string;
15
+ description: string;
16
+ };
17
+ message: {
18
+ type: string;
19
+ description: string;
20
+ };
21
+ title: {
22
+ type: string;
23
+ description: string;
24
+ };
25
+ severity: {
26
+ type: string;
27
+ description: string;
28
+ };
29
+ };
30
+ required: string[];
31
+ };
32
+ execute(args: Record<string, unknown>): Promise<string>;
33
+ private sendSlack;
34
+ private sendDiscord;
35
+ private sendGeneric;
36
+ private post;
37
+ }
38
+ //# sourceMappingURL=notification.d.ts.map
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NotificationTool = void 0;
4
+ class NotificationTool {
5
+ name = 'notification';
6
+ description = 'Send notifications via webhook (Slack, Discord, or generic). Actions: slack, discord, webhook.';
7
+ permission = 'prompt';
8
+ parameters = {
9
+ type: 'object',
10
+ properties: {
11
+ action: { type: 'string', description: 'Action: slack, discord, webhook' },
12
+ url: { type: 'string', description: 'Webhook URL' },
13
+ message: { type: 'string', description: 'Message text' },
14
+ title: { type: 'string', description: 'Optional title/subject' },
15
+ severity: { type: 'string', description: 'Severity: info, warning, error, success (affects color)' },
16
+ },
17
+ required: ['action', 'url', 'message'],
18
+ };
19
+ async execute(args) {
20
+ const action = args.action;
21
+ const url = args.url;
22
+ const message = args.message;
23
+ if (!action)
24
+ return 'Error: action is required';
25
+ if (!url)
26
+ return 'Error: url is required';
27
+ if (!message)
28
+ return 'Error: message is required';
29
+ // Validate URL
30
+ try {
31
+ new URL(url);
32
+ }
33
+ catch {
34
+ return `Error: invalid URL: ${url}`;
35
+ }
36
+ const title = args.title || '';
37
+ const severity = args.severity || 'info';
38
+ switch (action) {
39
+ case 'slack': return this.sendSlack(url, message, title, severity);
40
+ case 'discord': return this.sendDiscord(url, message, title, severity);
41
+ case 'webhook': return this.sendGeneric(url, message, title, severity);
42
+ default: return `Error: unknown action "${action}". Use: slack, discord, webhook`;
43
+ }
44
+ }
45
+ async sendSlack(url, message, title, severity) {
46
+ const colors = { info: '#2196F3', warning: '#FF9800', error: '#F44336', success: '#4CAF50' };
47
+ const payload = {
48
+ attachments: [{
49
+ color: colors[severity] || colors.info,
50
+ title: title || undefined,
51
+ text: message,
52
+ ts: Math.floor(Date.now() / 1000),
53
+ }],
54
+ };
55
+ return this.post(url, payload);
56
+ }
57
+ async sendDiscord(url, message, title, severity) {
58
+ const colors = { info: 0x2196F3, warning: 0xFF9800, error: 0xF44336, success: 0x4CAF50 };
59
+ const payload = {
60
+ embeds: [{
61
+ title: title || undefined,
62
+ description: message,
63
+ color: colors[severity] || colors.info,
64
+ timestamp: new Date().toISOString(),
65
+ }],
66
+ };
67
+ return this.post(url, payload);
68
+ }
69
+ async sendGeneric(url, message, title, severity) {
70
+ const payload = { title, message, severity, timestamp: new Date().toISOString() };
71
+ return this.post(url, payload);
72
+ }
73
+ async post(url, payload) {
74
+ const controller = new AbortController();
75
+ const timer = setTimeout(() => controller.abort(), 15_000);
76
+ try {
77
+ const res = await fetch(url, {
78
+ method: 'POST',
79
+ headers: { 'Content-Type': 'application/json' },
80
+ body: JSON.stringify(payload),
81
+ signal: controller.signal,
82
+ });
83
+ clearTimeout(timer);
84
+ if (res.ok)
85
+ return `Notification sent (${res.status}).`;
86
+ const body = await res.text().catch(() => '');
87
+ return `Error: webhook returned ${res.status} ${res.statusText}${body ? `: ${body.substring(0, 200)}` : ''}`;
88
+ }
89
+ catch (err) {
90
+ clearTimeout(timer);
91
+ return `Error: ${err instanceof Error ? err.message : String(err)}`;
92
+ }
93
+ }
94
+ }
95
+ exports.NotificationTool = NotificationTool;
96
+ //# sourceMappingURL=notification.js.map
@@ -0,0 +1,31 @@
1
+ import { Tool } from '../types';
2
+ export declare class PackageManagerTool 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
+ };
13
+ package: {
14
+ type: string;
15
+ description: string;
16
+ };
17
+ cwd: {
18
+ type: string;
19
+ description: string;
20
+ };
21
+ manager: {
22
+ type: string;
23
+ description: string;
24
+ };
25
+ };
26
+ required: string[];
27
+ };
28
+ execute(args: Record<string, unknown>): Promise<string>;
29
+ private detect;
30
+ }
31
+ //# sourceMappingURL=package-manager.d.ts.map
@@ -0,0 +1,161 @@
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.PackageManagerTool = void 0;
37
+ const child_process_1 = require("child_process");
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ const MANAGERS = {
41
+ npm: {
42
+ name: 'npm', install: 'npm install', add: 'npm install',
43
+ remove: 'npm uninstall', list: 'npm ls --depth=0', outdated: 'npm outdated', audit: 'npm audit',
44
+ },
45
+ yarn: {
46
+ name: 'yarn', install: 'yarn install', add: 'yarn add',
47
+ remove: 'yarn remove', list: 'yarn list --depth=0', outdated: 'yarn outdated', audit: 'yarn audit',
48
+ },
49
+ pnpm: {
50
+ name: 'pnpm', install: 'pnpm install', add: 'pnpm add',
51
+ remove: 'pnpm remove', list: 'pnpm ls --depth=0', outdated: 'pnpm outdated', audit: 'pnpm audit',
52
+ },
53
+ pip: {
54
+ name: 'pip', install: 'pip install -r requirements.txt', add: 'pip install',
55
+ remove: 'pip uninstall -y', list: 'pip list', outdated: 'pip list --outdated', audit: 'pip audit',
56
+ },
57
+ cargo: {
58
+ name: 'cargo', install: 'cargo build', add: 'cargo add',
59
+ remove: 'cargo remove', list: 'cargo tree --depth=1', outdated: 'cargo outdated', audit: 'cargo audit',
60
+ },
61
+ go: {
62
+ name: 'go', install: 'go mod download', add: 'go get',
63
+ remove: 'go mod tidy', list: 'go list -m all', outdated: 'go list -m -u all', audit: 'govulncheck ./...',
64
+ },
65
+ };
66
+ class PackageManagerTool {
67
+ name = 'package_manager';
68
+ description = 'Manage dependencies. Auto-detects npm/yarn/pnpm/pip/cargo/go. Actions: install, add, remove, list, outdated, audit, detect.';
69
+ permission = 'prompt';
70
+ parameters = {
71
+ type: 'object',
72
+ properties: {
73
+ action: { type: 'string', description: 'Action: install, add, remove, list, outdated, audit, detect' },
74
+ package: { type: 'string', description: 'Package name (for add/remove)' },
75
+ cwd: { type: 'string', description: 'Working directory' },
76
+ manager: { type: 'string', description: 'Force specific manager (npm, yarn, pnpm, pip, cargo, go)' },
77
+ },
78
+ required: ['action'],
79
+ };
80
+ async execute(args) {
81
+ const action = args.action;
82
+ if (!action)
83
+ return 'Error: action is required';
84
+ const cwd = args.cwd || process.cwd();
85
+ if (action === 'detect') {
86
+ const mgr = this.detect(cwd, args.manager);
87
+ return mgr ? `Detected: ${mgr.name}` : 'No package manager detected.';
88
+ }
89
+ const mgr = this.detect(cwd, args.manager);
90
+ if (!mgr)
91
+ return 'Error: no package manager detected. Specify with manager parameter.';
92
+ let cmd;
93
+ switch (action) {
94
+ case 'install':
95
+ cmd = mgr.install;
96
+ break;
97
+ case 'add': {
98
+ const pkg = args.package;
99
+ if (!pkg)
100
+ return 'Error: package name is required for add';
101
+ cmd = `${mgr.add} ${pkg}`;
102
+ break;
103
+ }
104
+ case 'remove': {
105
+ const pkg = args.package;
106
+ if (!pkg)
107
+ return 'Error: package name is required for remove';
108
+ cmd = `${mgr.remove} ${pkg}`;
109
+ break;
110
+ }
111
+ case 'list':
112
+ cmd = mgr.list;
113
+ break;
114
+ case 'outdated':
115
+ cmd = mgr.outdated;
116
+ break;
117
+ case 'audit':
118
+ cmd = mgr.audit;
119
+ break;
120
+ default: return `Error: unknown action "${action}". Use: install, add, remove, list, outdated, audit, detect`;
121
+ }
122
+ try {
123
+ const output = (0, child_process_1.execSync)(cmd, {
124
+ cwd,
125
+ timeout: 120_000,
126
+ maxBuffer: 2 * 1024 * 1024,
127
+ encoding: 'utf-8',
128
+ stdio: ['pipe', 'pipe', 'pipe'],
129
+ });
130
+ return output.trim() || '(no output)';
131
+ }
132
+ catch (err) {
133
+ const e = err;
134
+ // Audit and outdated commands often exit non-zero when issues are found
135
+ if (['audit', 'outdated'].includes(action) && e.stdout) {
136
+ return e.stdout.trim();
137
+ }
138
+ return `Exit ${e.status || 1}:\n${(e.stdout || '').trim()}\n${(e.stderr || '').trim()}`.trim();
139
+ }
140
+ }
141
+ detect(cwd, forced) {
142
+ if (forced && MANAGERS[forced])
143
+ return MANAGERS[forced];
144
+ // Check lock files
145
+ if (fs.existsSync(path.join(cwd, 'pnpm-lock.yaml')))
146
+ return MANAGERS.pnpm;
147
+ if (fs.existsSync(path.join(cwd, 'yarn.lock')))
148
+ return MANAGERS.yarn;
149
+ if (fs.existsSync(path.join(cwd, 'package-lock.json')) || fs.existsSync(path.join(cwd, 'package.json')))
150
+ return MANAGERS.npm;
151
+ if (fs.existsSync(path.join(cwd, 'requirements.txt')) || fs.existsSync(path.join(cwd, 'setup.py')) || fs.existsSync(path.join(cwd, 'pyproject.toml')))
152
+ return MANAGERS.pip;
153
+ if (fs.existsSync(path.join(cwd, 'Cargo.toml')))
154
+ return MANAGERS.cargo;
155
+ if (fs.existsSync(path.join(cwd, 'go.mod')))
156
+ return MANAGERS.go;
157
+ return null;
158
+ }
159
+ }
160
+ exports.PackageManagerTool = PackageManagerTool;
161
+ //# sourceMappingURL=package-manager.js.map
@@ -0,0 +1,33 @@
1
+ import { Tool } from '../types';
2
+ export declare class PdfExtractTool 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
+ };
13
+ path: {
14
+ type: string;
15
+ description: string;
16
+ };
17
+ max_pages: {
18
+ type: string;
19
+ description: string;
20
+ };
21
+ };
22
+ required: string[];
23
+ };
24
+ execute(args: Record<string, unknown>): Promise<string>;
25
+ private extractText;
26
+ private getInfo;
27
+ private countPages;
28
+ private estimatePageCount;
29
+ private extractFromBuffer;
30
+ private decodePdfString;
31
+ private extractMeta;
32
+ }
33
+ //# sourceMappingURL=pdf-extract.d.ts.map