codebot-ai 1.2.3 → 1.4.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.
Files changed (42) hide show
  1. package/README.md +135 -116
  2. package/dist/agent.js +51 -27
  3. package/dist/cli.js +18 -2
  4. package/dist/providers/anthropic.js +38 -18
  5. package/dist/providers/openai.js +35 -14
  6. package/dist/retry.d.ts +22 -0
  7. package/dist/retry.js +59 -0
  8. package/dist/scheduler.d.ts +2 -0
  9. package/dist/scheduler.js +25 -17
  10. package/dist/tools/code-analysis.d.ts +33 -0
  11. package/dist/tools/code-analysis.js +232 -0
  12. package/dist/tools/code-review.d.ts +32 -0
  13. package/dist/tools/code-review.js +228 -0
  14. package/dist/tools/database.d.ts +35 -0
  15. package/dist/tools/database.js +129 -0
  16. package/dist/tools/diff-viewer.d.ts +39 -0
  17. package/dist/tools/diff-viewer.js +145 -0
  18. package/dist/tools/docker.d.ts +26 -0
  19. package/dist/tools/docker.js +101 -0
  20. package/dist/tools/git.d.ts +26 -0
  21. package/dist/tools/git.js +58 -0
  22. package/dist/tools/http-client.d.ts +39 -0
  23. package/dist/tools/http-client.js +114 -0
  24. package/dist/tools/image-info.d.ts +23 -0
  25. package/dist/tools/image-info.js +170 -0
  26. package/dist/tools/index.js +34 -0
  27. package/dist/tools/multi-search.d.ts +28 -0
  28. package/dist/tools/multi-search.js +153 -0
  29. package/dist/tools/notification.d.ts +38 -0
  30. package/dist/tools/notification.js +96 -0
  31. package/dist/tools/package-manager.d.ts +31 -0
  32. package/dist/tools/package-manager.js +161 -0
  33. package/dist/tools/pdf-extract.d.ts +33 -0
  34. package/dist/tools/pdf-extract.js +178 -0
  35. package/dist/tools/ssh-remote.d.ts +39 -0
  36. package/dist/tools/ssh-remote.js +84 -0
  37. package/dist/tools/task-planner.d.ts +42 -0
  38. package/dist/tools/task-planner.js +161 -0
  39. package/dist/tools/test-runner.d.ts +36 -0
  40. package/dist/tools/test-runner.js +193 -0
  41. package/dist/tools/web-fetch.js +11 -2
  42. package/package.json +16 -8
@@ -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
@@ -0,0 +1,178 @@
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.PdfExtractTool = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ class PdfExtractTool {
40
+ name = 'pdf_extract';
41
+ description = 'Extract text and metadata from PDF files. Actions: text, info, pages.';
42
+ permission = 'auto';
43
+ parameters = {
44
+ type: 'object',
45
+ properties: {
46
+ action: { type: 'string', description: 'Action: text (extract text), info (file info), pages (page count)' },
47
+ path: { type: 'string', description: 'Path to PDF file' },
48
+ max_pages: { type: 'number', description: 'Max pages to extract (default: 10)' },
49
+ },
50
+ required: ['action', 'path'],
51
+ };
52
+ async execute(args) {
53
+ const action = args.action;
54
+ const filePath = args.path;
55
+ if (!action)
56
+ return 'Error: action is required';
57
+ if (!filePath)
58
+ return 'Error: path is required';
59
+ if (!fs.existsSync(filePath))
60
+ return `Error: file not found: ${filePath}`;
61
+ const ext = path.extname(filePath).toLowerCase();
62
+ if (ext !== '.pdf')
63
+ return `Error: not a PDF file (got ${ext})`;
64
+ switch (action) {
65
+ case 'text': return this.extractText(filePath, args);
66
+ case 'info': return this.getInfo(filePath);
67
+ case 'pages': return this.countPages(filePath);
68
+ default: return `Error: unknown action "${action}". Use: text, info, pages`;
69
+ }
70
+ }
71
+ extractText(filePath, args) {
72
+ const maxPages = args.max_pages || 10;
73
+ try {
74
+ const content = fs.readFileSync(filePath);
75
+ const text = this.extractFromBuffer(content, maxPages);
76
+ if (!text.trim()) {
77
+ return 'No extractable text found. The PDF may contain scanned images or use non-standard encoding.';
78
+ }
79
+ return `Extracted text from ${path.basename(filePath)}:\n\n${text}`;
80
+ }
81
+ catch (err) {
82
+ return `Error: ${err instanceof Error ? err.message : 'failed to read PDF'}`;
83
+ }
84
+ }
85
+ getInfo(filePath) {
86
+ const stat = fs.statSync(filePath);
87
+ const sizeMB = (stat.size / (1024 * 1024)).toFixed(2);
88
+ const content = fs.readFileSync(filePath);
89
+ const pages = this.estimatePageCount(content);
90
+ // Extract PDF metadata
91
+ const text = content.toString('latin1');
92
+ const title = this.extractMeta(text, 'Title');
93
+ const author = this.extractMeta(text, 'Author');
94
+ const creator = this.extractMeta(text, 'Creator');
95
+ let result = `File: ${path.basename(filePath)}\nSize: ${sizeMB} MB\nPages: ~${pages}\nModified: ${stat.mtime.toISOString()}`;
96
+ if (title)
97
+ result += `\nTitle: ${title}`;
98
+ if (author)
99
+ result += `\nAuthor: ${author}`;
100
+ if (creator)
101
+ result += `\nCreator: ${creator}`;
102
+ return result;
103
+ }
104
+ countPages(filePath) {
105
+ const content = fs.readFileSync(filePath);
106
+ const pages = this.estimatePageCount(content);
107
+ return `${path.basename(filePath)}: approximately ${pages} page(s)`;
108
+ }
109
+ estimatePageCount(buf) {
110
+ // Count /Type /Page occurrences (not /Pages)
111
+ const text = buf.toString('latin1');
112
+ const matches = text.match(/\/Type\s*\/Page(?!\s*s)/g);
113
+ return matches ? matches.length : 1;
114
+ }
115
+ extractFromBuffer(buf, maxPages) {
116
+ // Simple text extraction — find text between BT/ET markers and decode
117
+ const text = buf.toString('latin1');
118
+ const chunks = [];
119
+ let pageCount = 0;
120
+ // Find stream content
121
+ const streamRegex = /stream\r?\n([\s\S]*?)endstream/g;
122
+ let match;
123
+ while ((match = streamRegex.exec(text)) !== null && pageCount < maxPages) {
124
+ const stream = match[1];
125
+ // Extract text from BT...ET blocks
126
+ const btRegex = /BT\s([\s\S]*?)ET/g;
127
+ let btMatch;
128
+ while ((btMatch = btRegex.exec(stream)) !== null) {
129
+ const block = btMatch[1];
130
+ // Extract text strings in parentheses: (Hello World) Tj
131
+ const tjRegex = /\(([^)]*)\)\s*Tj/g;
132
+ let tjMatch;
133
+ while ((tjMatch = tjRegex.exec(block)) !== null) {
134
+ const decoded = this.decodePdfString(tjMatch[1]);
135
+ if (decoded.trim())
136
+ chunks.push(decoded);
137
+ }
138
+ // Extract TJ arrays: [(text1) 10 (text2)] TJ
139
+ const tjArrayRegex = /\[(.*?)\]\s*TJ/g;
140
+ let arrMatch;
141
+ while ((arrMatch = tjArrayRegex.exec(block)) !== null) {
142
+ const inner = arrMatch[1];
143
+ const strRegex = /\(([^)]*)\)/g;
144
+ let strMatch;
145
+ const parts = [];
146
+ while ((strMatch = strRegex.exec(inner)) !== null) {
147
+ parts.push(this.decodePdfString(strMatch[1]));
148
+ }
149
+ if (parts.length > 0)
150
+ chunks.push(parts.join(''));
151
+ }
152
+ }
153
+ if (chunks.length > 0)
154
+ pageCount++;
155
+ }
156
+ // Clean up and join
157
+ return chunks
158
+ .map(c => c.trim())
159
+ .filter(c => c.length > 0)
160
+ .join('\n')
161
+ .substring(0, 20_000);
162
+ }
163
+ decodePdfString(s) {
164
+ return s
165
+ .replace(/\\n/g, '\n')
166
+ .replace(/\\r/g, '\r')
167
+ .replace(/\\t/g, '\t')
168
+ .replace(/\\\\/g, '\\')
169
+ .replace(/\\([()])/g, '$1');
170
+ }
171
+ extractMeta(text, key) {
172
+ const regex = new RegExp(`/${key}\\s*\\(([^)]*)\\)`);
173
+ const match = text.match(regex);
174
+ return match ? match[1] : null;
175
+ }
176
+ }
177
+ exports.PdfExtractTool = PdfExtractTool;
178
+ //# sourceMappingURL=pdf-extract.js.map
@@ -0,0 +1,39 @@
1
+ import { Tool } from '../types';
2
+ export declare class SshRemoteTool 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
+ host: {
14
+ type: string;
15
+ description: string;
16
+ };
17
+ command: {
18
+ type: string;
19
+ description: string;
20
+ };
21
+ local_path: {
22
+ type: string;
23
+ description: string;
24
+ };
25
+ remote_path: {
26
+ type: string;
27
+ description: string;
28
+ };
29
+ port: {
30
+ type: string;
31
+ description: string;
32
+ };
33
+ };
34
+ required: string[];
35
+ };
36
+ execute(args: Record<string, unknown>): Promise<string>;
37
+ private runSsh;
38
+ }
39
+ //# sourceMappingURL=ssh-remote.d.ts.map
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SshRemoteTool = void 0;
4
+ const child_process_1 = require("child_process");
5
+ // Block shell injection characters in host/user inputs
6
+ const SAFE_HOST = /^[a-zA-Z0-9._\-@:]+$/;
7
+ class SshRemoteTool {
8
+ name = 'ssh_remote';
9
+ description = 'Execute commands on remote servers via SSH, or upload/download files via SCP. Actions: exec, upload, download.';
10
+ permission = 'always-ask';
11
+ parameters = {
12
+ type: 'object',
13
+ properties: {
14
+ action: { type: 'string', description: 'Action: exec, upload, download' },
15
+ host: { type: 'string', description: 'SSH target (user@hostname or hostname)' },
16
+ command: { type: 'string', description: 'Command to execute remotely (for exec)' },
17
+ local_path: { type: 'string', description: 'Local file path (for upload/download)' },
18
+ remote_path: { type: 'string', description: 'Remote file path (for upload/download)' },
19
+ port: { type: 'number', description: 'SSH port (default: 22)' },
20
+ },
21
+ required: ['action', 'host'],
22
+ };
23
+ async execute(args) {
24
+ const action = args.action;
25
+ const host = args.host;
26
+ if (!action)
27
+ return 'Error: action is required';
28
+ if (!host)
29
+ return 'Error: host is required';
30
+ if (!SAFE_HOST.test(host))
31
+ return 'Error: host contains invalid characters (possible injection)';
32
+ const port = args.port || 22;
33
+ const portFlag = port !== 22 ? `-p ${port}` : '';
34
+ const scpPortFlag = port !== 22 ? `-P ${port}` : '';
35
+ switch (action) {
36
+ case 'exec': {
37
+ const cmd = args.command;
38
+ if (!cmd)
39
+ return 'Error: command is required for exec';
40
+ return this.runSsh(`ssh ${portFlag} -o ConnectTimeout=10 -o StrictHostKeyChecking=accept-new ${host} ${JSON.stringify(cmd)}`);
41
+ }
42
+ case 'upload': {
43
+ const local = args.local_path;
44
+ const remote = args.remote_path;
45
+ if (!local || !remote)
46
+ return 'Error: local_path and remote_path are required';
47
+ return this.runSsh(`scp ${scpPortFlag} -o ConnectTimeout=10 "${local}" ${host}:"${remote}"`);
48
+ }
49
+ case 'download': {
50
+ const local = args.local_path;
51
+ const remote = args.remote_path;
52
+ if (!local || !remote)
53
+ return 'Error: local_path and remote_path are required';
54
+ return this.runSsh(`scp ${scpPortFlag} -o ConnectTimeout=10 ${host}:"${remote}" "${local}"`);
55
+ }
56
+ default:
57
+ return `Error: unknown action "${action}". Use: exec, upload, download`;
58
+ }
59
+ }
60
+ runSsh(cmd) {
61
+ try {
62
+ const output = (0, child_process_1.execSync)(cmd, {
63
+ timeout: 60_000,
64
+ maxBuffer: 2 * 1024 * 1024,
65
+ encoding: 'utf-8',
66
+ stdio: ['pipe', 'pipe', 'pipe'],
67
+ });
68
+ return output.trim() || '(no output)';
69
+ }
70
+ catch (err) {
71
+ const e = err;
72
+ const msg = (e.stderr || 'SSH command failed').trim();
73
+ if (msg.includes('Connection refused') || msg.includes('Connection timed out')) {
74
+ return `Error: could not connect to host. ${msg}`;
75
+ }
76
+ if (msg.includes('Permission denied')) {
77
+ return 'Error: authentication failed. Check SSH key or credentials.';
78
+ }
79
+ return `Exit ${e.status || 1}: ${msg}`;
80
+ }
81
+ }
82
+ }
83
+ exports.SshRemoteTool = SshRemoteTool;
84
+ //# sourceMappingURL=ssh-remote.js.map
@@ -0,0 +1,42 @@
1
+ import { Tool } from '../types';
2
+ export declare class TaskPlannerTool 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
+ title: {
14
+ type: string;
15
+ description: string;
16
+ };
17
+ id: {
18
+ type: string;
19
+ description: string;
20
+ };
21
+ priority: {
22
+ type: string;
23
+ description: string;
24
+ };
25
+ status: {
26
+ type: string;
27
+ description: string;
28
+ };
29
+ };
30
+ required: string[];
31
+ };
32
+ execute(args: Record<string, unknown>): Promise<string>;
33
+ private addTask;
34
+ private listTasks;
35
+ private updateTask;
36
+ private completeTask;
37
+ private removeTask;
38
+ private clearDone;
39
+ private load;
40
+ private save;
41
+ }
42
+ //# sourceMappingURL=task-planner.d.ts.map