| 141 | |
| 142 | // ── Tool execution ───────────────────────────────────────────────────────────── |
| 143 | |
| 144 | function execTool(toolName, toolInput, sandbox) { |
| 145 | if (toolName === 'Edit' || toolName === 'Write') { |
| 146 | const filePath = toolInput.file_path || toolInput.path; |
| 147 | fs.mkdirSync(path.dirname(filePath), { recursive: true }); |
| 148 | fs.writeFileSync(filePath, toolInput.content || toolInput.new_string || ''); |
| 149 | return { type: 'edit', path: filePath }; |
| 150 | } |
| 151 | if (toolName === 'Read') { |
| 152 | try { |
| 153 | return { type: 'read', content: fs.readFileSync(toolInput.file_path, 'utf8') }; |
| 154 | } catch (e) { |
| 155 | return { type: 'read', error: e.message }; |
| 156 | } |
| 157 | } |
| 158 | if (toolName === 'Bash') { |
| 159 | const r = spawnSync(toolInput.command, { shell: true, cwd: sandbox, encoding: 'utf8', timeout: 5000 }); |
| 160 | return { type: 'bash', stdout: r.stdout, stderr: r.stderr, exitCode: r.status }; |
| 161 | } |
| 162 | return { type: 'noop' }; |
| 163 | } |
| 164 | |
| 165 | // ── Telemetry helpers ────────────────────────────────────────────────────────── |