@dastageer_44/eco-code 1.1.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/LICENSE +21 -0
  2. package/README.md +105 -0
  3. package/dist/config.d.ts +44 -0
  4. package/dist/config.js +111 -0
  5. package/dist/config.js.map +1 -0
  6. package/dist/harness/agent.d.ts +51 -0
  7. package/dist/harness/agent.js +168 -0
  8. package/dist/harness/agent.js.map +1 -0
  9. package/dist/harness/context.d.ts +17 -0
  10. package/dist/harness/context.js +77 -0
  11. package/dist/harness/context.js.map +1 -0
  12. package/dist/index.d.ts +2 -0
  13. package/dist/index.js +414 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/services/openrouter.d.ts +21 -0
  16. package/dist/services/openrouter.js +106 -0
  17. package/dist/services/openrouter.js.map +1 -0
  18. package/dist/services/updater.d.ts +6 -0
  19. package/dist/services/updater.js +61 -0
  20. package/dist/services/updater.js.map +1 -0
  21. package/dist/taste/engine.d.ts +10 -0
  22. package/dist/taste/engine.js +80 -0
  23. package/dist/taste/engine.js.map +1 -0
  24. package/dist/tools/file-ops.d.ts +18 -0
  25. package/dist/tools/file-ops.js +89 -0
  26. package/dist/tools/file-ops.js.map +1 -0
  27. package/dist/tools/index.d.ts +5 -0
  28. package/dist/tools/index.js +235 -0
  29. package/dist/tools/index.js.map +1 -0
  30. package/dist/tools/search-ops.d.ts +5 -0
  31. package/dist/tools/search-ops.js +55 -0
  32. package/dist/tools/search-ops.js.map +1 -0
  33. package/dist/tools/shell-ops.d.ts +18 -0
  34. package/dist/tools/shell-ops.js +140 -0
  35. package/dist/tools/shell-ops.js.map +1 -0
  36. package/dist/tools/types.d.ts +11 -0
  37. package/dist/tools/types.js +2 -0
  38. package/dist/tools/types.js.map +1 -0
  39. package/dist/ui/banner.d.ts +2 -0
  40. package/dist/ui/banner.js +31 -0
  41. package/dist/ui/banner.js.map +1 -0
  42. package/package.json +53 -0
@@ -0,0 +1,10 @@
1
+ export declare class TasteEngine {
2
+ private tasteDir;
3
+ private tasteFile;
4
+ private workspaceDir;
5
+ constructor(workspaceDir?: string);
6
+ private ensureInitialized;
7
+ private detectRepoSignals;
8
+ getTastePrompt(): string;
9
+ addDirective(directive: string): void;
10
+ }
@@ -0,0 +1,80 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ export class TasteEngine {
4
+ tasteDir;
5
+ tasteFile;
6
+ workspaceDir;
7
+ constructor(workspaceDir = process.cwd()) {
8
+ this.workspaceDir = workspaceDir;
9
+ this.tasteDir = path.join(this.workspaceDir, '.agent');
10
+ this.tasteFile = path.join(this.tasteDir, 'taste.md');
11
+ this.ensureInitialized();
12
+ }
13
+ ensureInitialized() {
14
+ if (!fs.existsSync(this.tasteDir)) {
15
+ try {
16
+ fs.mkdirSync(this.tasteDir, { recursive: true });
17
+ }
18
+ catch { }
19
+ }
20
+ if (!fs.existsSync(this.tasteFile)) {
21
+ const initialRules = this.detectRepoSignals();
22
+ const defaultContent = `# Coding Taste & Project Directives
23
+
24
+ - Write clean, modular, and well-typed code.
25
+ - Prefer minimal and non-breaking edits over full file rewrites.
26
+ - Follow existing naming patterns, folder conventions, and style.
27
+ ${initialRules}
28
+ `;
29
+ try {
30
+ fs.writeFileSync(this.tasteFile, defaultContent, 'utf-8');
31
+ }
32
+ catch { }
33
+ }
34
+ }
35
+ detectRepoSignals() {
36
+ const signals = [];
37
+ try {
38
+ if (fs.existsSync(path.join(this.workspaceDir, 'tsconfig.json'))) {
39
+ signals.push('- TypeScript environment: adhere to strict type checking and avoid `any`.');
40
+ }
41
+ if (fs.existsSync(path.join(this.workspaceDir, 'package.json'))) {
42
+ const pkg = JSON.parse(fs.readFileSync(path.join(this.workspaceDir, 'package.json'), 'utf-8'));
43
+ if (pkg.dependencies?.react || pkg.devDependencies?.react) {
44
+ signals.push('- React ecosystem: use functional components and hooks.');
45
+ }
46
+ if (pkg.devDependencies?.vitest || pkg.dependencies?.vitest) {
47
+ signals.push('- Testing: use Vitest for unit tests.');
48
+ }
49
+ else if (pkg.devDependencies?.jest || pkg.dependencies?.jest) {
50
+ signals.push('- Testing: use Jest for unit tests.');
51
+ }
52
+ }
53
+ if (fs.existsSync(path.join(this.workspaceDir, 'pyproject.toml')) || fs.existsSync(path.join(this.workspaceDir, 'requirements.txt'))) {
54
+ signals.push('- Python environment: adhere to PEP8 and type annotations.');
55
+ }
56
+ if (fs.existsSync(path.join(this.workspaceDir, 'Cargo.toml'))) {
57
+ signals.push('- Rust environment: write idiomatic, safe Rust with proper error handling.');
58
+ }
59
+ }
60
+ catch { }
61
+ return signals.length > 0 ? signals.join('\n') : '';
62
+ }
63
+ getTastePrompt() {
64
+ try {
65
+ if (fs.existsSync(this.tasteFile)) {
66
+ return fs.readFileSync(this.tasteFile, 'utf-8');
67
+ }
68
+ }
69
+ catch { }
70
+ return '';
71
+ }
72
+ addDirective(directive) {
73
+ try {
74
+ this.ensureInitialized();
75
+ fs.appendFileSync(this.tasteFile, `\n- ${directive.trim()}`);
76
+ }
77
+ catch { }
78
+ }
79
+ }
80
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/taste/engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export declare function readFile(args: {
2
+ path: string;
3
+ start_line?: number;
4
+ end_line?: number;
5
+ }, cwd?: string): Promise<string>;
6
+ export declare function writeFile(args: {
7
+ path: string;
8
+ content: string;
9
+ }, cwd?: string): Promise<string>;
10
+ export declare function replaceInFile(args: {
11
+ path: string;
12
+ target_content: string;
13
+ replacement_content: string;
14
+ }, cwd?: string): Promise<string>;
15
+ export declare function listDir(args: {
16
+ path?: string;
17
+ max_depth?: number;
18
+ }, cwd?: string): Promise<string>;
@@ -0,0 +1,89 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ export async function readFile(args, cwd = process.cwd()) {
4
+ const resolved = path.resolve(cwd, args.path);
5
+ if (!fs.existsSync(resolved)) {
6
+ return `Error: File '${args.path}' does not exist.`;
7
+ }
8
+ const stat = fs.statSync(resolved);
9
+ if (stat.isDirectory()) {
10
+ return `Error: '${args.path}' is a directory, not a file. Use list_dir instead.`;
11
+ }
12
+ if (stat.size > 1024 * 1024) { // hard limit 1MB for safety
13
+ return `Error: File '${args.path}' is too large to read safely (> 1MB).`;
14
+ }
15
+ const content = fs.readFileSync(resolved, 'utf-8');
16
+ const lines = content.split('\n');
17
+ const maxLines = 2000;
18
+ let start = 0;
19
+ let end = lines.length;
20
+ if (args.start_line !== undefined || args.end_line !== undefined) {
21
+ start = Math.max(1, args.start_line || 1) - 1;
22
+ end = Math.min(lines.length, args.end_line || lines.length);
23
+ }
24
+ let truncated = false;
25
+ if (end - start > maxLines) {
26
+ end = start + maxLines;
27
+ truncated = true;
28
+ }
29
+ const sliced = lines.slice(start, end).map((l, i) => `${start + i + 1}: ${l}`);
30
+ let result = sliced.join('\n');
31
+ if (truncated) {
32
+ result += `\n\n--- Note: output truncated at line window (resume at start_line=${end + 1}) ---`;
33
+ }
34
+ return result;
35
+ }
36
+ export async function writeFile(args, cwd = process.cwd()) {
37
+ const resolved = path.resolve(cwd, args.path);
38
+ fs.mkdirSync(path.dirname(resolved), { recursive: true });
39
+ fs.writeFileSync(resolved, args.content, 'utf-8');
40
+ return `Successfully wrote ${args.content.length} characters to '${args.path}'.`;
41
+ }
42
+ export async function replaceInFile(args, cwd = process.cwd()) {
43
+ const resolved = path.resolve(cwd, args.path);
44
+ if (!fs.existsSync(resolved)) {
45
+ return `Error: File '${args.path}' does not exist.`;
46
+ }
47
+ const content = fs.readFileSync(resolved, 'utf-8');
48
+ if (!content.includes(args.target_content)) {
49
+ return `Error: target_content was not found in '${args.path}'. Ensure exact character/whitespace match.`;
50
+ }
51
+ const occurrences = content.split(args.target_content).length - 1;
52
+ if (occurrences > 1) {
53
+ return `Warning: target_content occurs ${occurrences} times in '${args.path}'. Please provide more surrounding context to disambiguate.`;
54
+ }
55
+ const updated = content.replace(args.target_content, args.replacement_content);
56
+ fs.writeFileSync(resolved, updated, 'utf-8');
57
+ return `Successfully replaced snippet in '${args.path}'.`;
58
+ }
59
+ export async function listDir(args, cwd = process.cwd()) {
60
+ const targetDir = path.resolve(cwd, args.path || '.');
61
+ if (!fs.existsSync(targetDir)) {
62
+ return `Error: Directory '${args.path || '.'}' does not exist.`;
63
+ }
64
+ const maxDepth = args.max_depth || 2;
65
+ const entries = [];
66
+ function traverse(dir, depth) {
67
+ if (depth > maxDepth)
68
+ return;
69
+ try {
70
+ const items = fs.readdirSync(dir, { withFileTypes: true });
71
+ for (const item of items) {
72
+ if (item.name.startsWith('.') || item.name === 'node_modules' || item.name === 'dist') {
73
+ continue;
74
+ }
75
+ const rel = path.relative(targetDir, path.join(dir, item.name));
76
+ entries.push(`${rel}${item.isDirectory() ? '/' : ''}`);
77
+ if (item.isDirectory()) {
78
+ traverse(path.join(dir, item.name), depth + 1);
79
+ }
80
+ }
81
+ }
82
+ catch (e) {
83
+ entries.push(`Error reading ${dir}: ${e.message}`);
84
+ }
85
+ }
86
+ traverse(targetDir, 1);
87
+ return entries.length > 0 ? entries.join('\n') : '(empty directory)';
88
+ }
89
+ //# sourceMappingURL=file-ops.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-ops.js","sourceRoot":"","sources":["../../src/tools/file-ops.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import OpenAI from 'openai';
2
+ import { ToolDefinition } from './types.js';
3
+ export declare const TOOLS: Record<string, ToolDefinition>;
4
+ export declare const TOOL_SCHEMAS: OpenAI.Chat.Completions.ChatCompletionTool[];
5
+ export declare function executeToolCall(name: string, rawArgs: any, cwd?: string): Promise<string>;
@@ -0,0 +1,235 @@
1
+ import { readFile, writeFile, replaceInFile, listDir } from './file-ops.js';
2
+ import { runCommand, getShellOutput, sleepTool, monitorCommand, listShellTasks } from './shell-ops.js';
3
+ import { grepSearch } from './search-ops.js';
4
+ export const TOOLS = {
5
+ read_file: {
6
+ schema: {
7
+ type: 'function',
8
+ function: {
9
+ name: 'read_file',
10
+ description: 'Read the contents of a file. For large files, it will return a window of lines (max 2000). Use start_line and end_line to navigate.',
11
+ parameters: {
12
+ type: 'object',
13
+ properties: {
14
+ path: { type: 'string', description: 'Relative path to the file' },
15
+ start_line: { type: 'number', description: 'Optional 1-indexed starting line' },
16
+ end_line: { type: 'number', description: 'Optional 1-indexed ending line' },
17
+ },
18
+ required: ['path'],
19
+ },
20
+ },
21
+ },
22
+ execute: (args, cwd) => readFile(args, cwd || process.cwd()),
23
+ },
24
+ write_file: {
25
+ schema: {
26
+ type: 'function',
27
+ function: {
28
+ name: 'write_file',
29
+ description: 'Create a new file or completely overwrite an existing file with the provided content.',
30
+ parameters: {
31
+ type: 'object',
32
+ properties: {
33
+ path: { type: 'string', description: 'Relative path to the file to create or overwrite' },
34
+ content: { type: 'string', description: 'The complete content of the file' },
35
+ },
36
+ required: ['path', 'content'],
37
+ },
38
+ },
39
+ },
40
+ execute: (args, cwd) => writeFile(args, cwd || process.cwd()),
41
+ },
42
+ replace_in_file: {
43
+ schema: {
44
+ type: 'function',
45
+ function: {
46
+ name: 'replace_in_file',
47
+ description: 'Replace an exact chunk of text in an existing file with replacement text. Provide enough context for target_content so it is unique.',
48
+ parameters: {
49
+ type: 'object',
50
+ properties: {
51
+ path: { type: 'string', description: 'Relative path to the file' },
52
+ target_content: { type: 'string', description: 'The exact text snippet to replace' },
53
+ replacement_content: { type: 'string', description: 'The new replacement text' },
54
+ },
55
+ required: ['path', 'target_content', 'replacement_content'],
56
+ },
57
+ },
58
+ },
59
+ execute: (args, cwd) => replaceInFile(args, cwd || process.cwd()),
60
+ },
61
+ run_command: {
62
+ schema: {
63
+ type: 'function',
64
+ function: {
65
+ name: 'run_command',
66
+ description: 'Execute a shell command. Set run_in_background=true for long-running commands (returns immediately with a task_id).',
67
+ parameters: {
68
+ type: 'object',
69
+ properties: {
70
+ command: { type: 'string', description: 'The exact command line string to run' },
71
+ run_in_background: { type: 'boolean', description: 'Run asynchronously and return task_id instead of blocking' },
72
+ timeout_ms: { type: 'number', description: 'Optional timeout in milliseconds (default: 45000)' },
73
+ },
74
+ required: ['command'],
75
+ },
76
+ },
77
+ },
78
+ execute: (args, cwd) => runCommand(args, cwd || process.cwd()),
79
+ },
80
+ shell_output: {
81
+ schema: {
82
+ type: 'function',
83
+ function: {
84
+ name: 'shell_output',
85
+ description: 'Read the output of a background shell task. Use from_offset to only read new bytes since the last read.',
86
+ parameters: {
87
+ type: 'object',
88
+ properties: {
89
+ task_id: { type: 'string', description: 'The task ID returned by run_command' },
90
+ from_offset: { type: 'number', description: 'Byte offset to start reading from' },
91
+ },
92
+ required: ['task_id'],
93
+ },
94
+ },
95
+ },
96
+ execute: (args, cwd) => getShellOutput(args, cwd || process.cwd()),
97
+ },
98
+ monitor_command: {
99
+ schema: {
100
+ type: 'function',
101
+ function: {
102
+ name: 'monitor_command',
103
+ description: 'Watch a background task. Blocks until the output matches a regex pattern or the process exits.',
104
+ parameters: {
105
+ type: 'object',
106
+ properties: {
107
+ task_id: { type: 'string', description: 'The task ID to monitor' },
108
+ pattern: { type: 'string', description: 'Optional regex pattern to wait for in the output' },
109
+ timeout_ms: { type: 'number', description: 'Optional maximum wait time in ms' },
110
+ },
111
+ required: ['task_id'],
112
+ },
113
+ },
114
+ },
115
+ execute: (args, cwd) => monitorCommand(args, cwd || process.cwd()),
116
+ },
117
+ list_shell_tasks: {
118
+ schema: {
119
+ type: 'function',
120
+ function: {
121
+ name: 'list_shell_tasks',
122
+ description: 'List all running background tasks and their statuses.',
123
+ parameters: {
124
+ type: 'object',
125
+ properties: {},
126
+ },
127
+ },
128
+ },
129
+ execute: (args, cwd) => listShellTasks(args, cwd || process.cwd()),
130
+ },
131
+ sleep: {
132
+ schema: {
133
+ type: 'function',
134
+ function: {
135
+ name: 'sleep',
136
+ description: 'Pause execution for a specified number of milliseconds.',
137
+ parameters: {
138
+ type: 'object',
139
+ properties: {
140
+ ms: { type: 'number', description: 'Milliseconds to sleep' },
141
+ },
142
+ required: ['ms'],
143
+ },
144
+ },
145
+ },
146
+ execute: (args, cwd) => sleepTool(args, cwd || process.cwd()),
147
+ },
148
+ list_dir: {
149
+ schema: {
150
+ type: 'function',
151
+ function: {
152
+ name: 'list_dir',
153
+ description: 'List the files and subdirectories within a given directory up to a specified depth.',
154
+ parameters: {
155
+ type: 'object',
156
+ properties: {
157
+ path: { type: 'string', description: 'Directory path to list (default: current directory ".")' },
158
+ max_depth: { type: 'number', description: 'Max depth of subdirectories to traverse (default: 2)' },
159
+ },
160
+ },
161
+ },
162
+ },
163
+ execute: (args, cwd) => listDir(args, cwd || process.cwd()),
164
+ },
165
+ grep_search: {
166
+ schema: {
167
+ type: 'function',
168
+ function: {
169
+ name: 'grep_search',
170
+ description: 'Search for text matches across all project files.',
171
+ parameters: {
172
+ type: 'object',
173
+ properties: {
174
+ query: { type: 'string', description: 'Text substring to search for' },
175
+ file_extension: { type: 'string', description: 'Optional file extension filter (e.g., "ts", "json")' },
176
+ is_case_sensitive: { type: 'boolean', description: 'Whether search is case-sensitive' },
177
+ },
178
+ required: ['query'],
179
+ },
180
+ },
181
+ },
182
+ execute: (args, cwd) => grepSearch(args, cwd || process.cwd()),
183
+ },
184
+ };
185
+ export const TOOL_SCHEMAS = Object.values(TOOLS).map((t) => t.schema);
186
+ /**
187
+ * Deterministic repair pipeline for common free model hallucinations.
188
+ */
189
+ function repairToolArgs(args, schema) {
190
+ if (typeof args !== 'object' || args === null)
191
+ return args;
192
+ const repaired = { ...args };
193
+ for (const [key, val] of Object.entries(repaired)) {
194
+ // 1. Strip null values for optional fields (JSON schema doesn't like null unless explicitly allowed)
195
+ if (val === null) {
196
+ delete repaired[key];
197
+ continue;
198
+ }
199
+ // 2. Fix stringified arrays: "{ 'files': '[\"a.js\"]' }" -> ["a.js"]
200
+ if (typeof val === 'string' && val.trim().startsWith('[') && val.trim().endsWith(']')) {
201
+ try {
202
+ const parsed = JSON.parse(val);
203
+ if (Array.isArray(parsed)) {
204
+ repaired[key] = parsed;
205
+ continue;
206
+ }
207
+ }
208
+ catch { }
209
+ }
210
+ // 3. (Optional) Coerce empty objects to arrays if the schema expects an array for this key
211
+ // This is a naive check; full schema traversal is better, but this handles common cases.
212
+ if (typeof val === 'object' && !Array.isArray(val) && Object.keys(val).length === 0) {
213
+ const propSchema = schema?.function?.parameters?.properties?.[key];
214
+ if (propSchema && propSchema.type === 'array') {
215
+ repaired[key] = [];
216
+ }
217
+ }
218
+ }
219
+ return repaired;
220
+ }
221
+ export async function executeToolCall(name, rawArgs, cwd = process.cwd()) {
222
+ const tool = TOOLS[name];
223
+ if (!tool) {
224
+ return `Error: Unknown tool "${name}".`;
225
+ }
226
+ // Repair arguments before execution
227
+ const args = repairToolArgs(rawArgs, tool.schema);
228
+ try {
229
+ return await tool.execute(args, cwd);
230
+ }
231
+ catch (err) {
232
+ return `Error executing tool ${name}: ${err.message}`;
233
+ }
234
+ }
235
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare function grepSearch(args: {
2
+ query: string;
3
+ file_extension?: string;
4
+ is_case_sensitive?: boolean;
5
+ }, cwd?: string): Promise<string>;
@@ -0,0 +1,55 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ export async function grepSearch(args, cwd = process.cwd()) {
4
+ const query = args.query;
5
+ const isCaseSensitive = !!args.is_case_sensitive;
6
+ const extFilter = args.file_extension ? (args.file_extension.startsWith('.') ? args.file_extension : `.${args.file_extension}`) : null;
7
+ const matches = [];
8
+ function searchInFile(filePath) {
9
+ try {
10
+ const content = fs.readFileSync(filePath, 'utf-8');
11
+ const lines = content.split('\n');
12
+ for (let i = 0; i < lines.length; i++) {
13
+ const line = lines[i];
14
+ const match = isCaseSensitive ? line.includes(query) : line.toLowerCase().includes(query.toLowerCase());
15
+ if (match) {
16
+ const rel = path.relative(cwd, filePath);
17
+ matches.push(`${rel}:${i + 1}: ${line.trim()}`);
18
+ if (matches.length >= 50)
19
+ return; // Limit results
20
+ }
21
+ }
22
+ }
23
+ catch {
24
+ // Ignore unreadable/binary files
25
+ }
26
+ }
27
+ function walk(dir) {
28
+ if (matches.length >= 50)
29
+ return;
30
+ try {
31
+ const items = fs.readdirSync(dir, { withFileTypes: true });
32
+ for (const item of items) {
33
+ if (item.name.startsWith('.') || item.name === 'node_modules' || item.name === 'dist') {
34
+ continue;
35
+ }
36
+ const full = path.join(dir, item.name);
37
+ if (item.isDirectory()) {
38
+ walk(full);
39
+ }
40
+ else if (item.isFile()) {
41
+ if (!extFilter || full.endsWith(extFilter)) {
42
+ searchInFile(full);
43
+ }
44
+ }
45
+ }
46
+ }
47
+ catch { }
48
+ }
49
+ walk(cwd);
50
+ if (matches.length === 0) {
51
+ return `No matches found for query: "${query}"`;
52
+ }
53
+ return matches.slice(0, 50).join('\n') + (matches.length >= 50 ? '\n(Results capped at 50 matches)' : '');
54
+ }
55
+ //# sourceMappingURL=search-ops.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-ops.js","sourceRoot":"","sources":["../../src/tools/search-ops.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export declare function runCommand(args: {
2
+ command: string;
3
+ timeout_ms?: number;
4
+ run_in_background?: boolean;
5
+ }, cwd?: string): Promise<string>;
6
+ export declare function getShellOutput(args: {
7
+ task_id: string;
8
+ from_offset?: number;
9
+ }, cwd: string): Promise<string>;
10
+ export declare function sleepTool(args: {
11
+ ms: number;
12
+ }, cwd: string): Promise<string>;
13
+ export declare function monitorCommand(args: {
14
+ task_id: string;
15
+ pattern?: string;
16
+ timeout_ms?: number;
17
+ }, cwd: string): Promise<string>;
18
+ export declare function listShellTasks(args: any, cwd: string): Promise<string>;