* Handles the confirmation prompt for the Edit tool in the CLI. * It needs to calculate the diff to show the user.
(
abortSignal: AbortSignal,
)
| 220 | * It needs to calculate the diff to show the user. |
| 221 | */ |
| 222 | async shouldConfirmExecute( |
| 223 | abortSignal: AbortSignal, |
| 224 | ): Promise<ToolCallConfirmationDetails | false> { |
| 225 | if (this.config.getApprovalMode() === ApprovalMode.AUTO_EDIT) { |
| 226 | return false; |
| 227 | } |
| 228 | |
| 229 | let editData: CalculatedEdit; |
| 230 | try { |
| 231 | editData = await this.calculateEdit(this.params, abortSignal); |
| 232 | } catch (error) { |
| 233 | const errorMsg = error instanceof Error ? error.message : String(error); |
| 234 | console.log(`Error preparing edit: ${errorMsg}`); |
| 235 | return false; |
| 236 | } |
| 237 | |
| 238 | if (editData.error) { |
| 239 | console.log(`Error: ${editData.error.display}`); |
| 240 | return false; |
| 241 | } |
| 242 | |
| 243 | const fileName = path.basename(this.params.file_path); |
| 244 | const fileDiff = Diff.createPatch( |
| 245 | fileName, |
| 246 | editData.currentContent ?? '', |
| 247 | editData.newContent, |
| 248 | 'Current', |
| 249 | 'Proposed', |
| 250 | DEFAULT_DIFF_OPTIONS, |
| 251 | ); |
| 252 | const ideClient = this.config.getIdeClient(); |
| 253 | const ideConfirmation = |
| 254 | this.config.getIdeMode() && |
| 255 | ideClient?.getConnectionStatus().status === IDEConnectionStatus.Connected |
| 256 | ? ideClient.openDiff(this.params.file_path, editData.newContent) |
| 257 | : undefined; |
| 258 | |
| 259 | const confirmationDetails: ToolEditConfirmationDetails = { |
| 260 | type: 'edit', |
| 261 | title: `Confirm Edit: ${shortenPath(makeRelative(this.params.file_path, this.config.getTargetDir()))}`, |
| 262 | fileName, |
| 263 | filePath: this.params.file_path, |
| 264 | fileDiff, |
| 265 | originalContent: editData.currentContent, |
| 266 | newContent: editData.newContent, |
| 267 | onConfirm: async (outcome: ToolConfirmationOutcome) => { |
| 268 | if (outcome === ToolConfirmationOutcome.ProceedAlways) { |
| 269 | this.config.setApprovalMode(ApprovalMode.AUTO_EDIT); |
| 270 | } |
| 271 | |
| 272 | if (ideConfirmation) { |
| 273 | const result = await ideConfirmation; |
| 274 | if (result.status === 'accepted' && result.content) { |
| 275 | // TODO(chrstn): See https://github.com/anus-dev/anus/pull/5618#discussion_r2255413084 |
| 276 | // for info on a possible race condition where the file is modified on disk while being edited. |
| 277 | this.params.old_string = editData.currentContent ?? ''; |
| 278 | this.params.new_string = result.content; |
| 279 | } |
nothing calls this directly
no test coverage detected