(input)
| 172 | return input.action |
| 173 | }, |
| 174 | async validateInput(input) { |
| 175 | // Scope guard: getCurrentWorktreeSession() is null unless EnterWorktree |
| 176 | // (specifically createWorktreeForSession) ran in THIS session. Worktrees |
| 177 | // created by `git worktree add`, or by EnterWorktree in a previous |
| 178 | // session, do not populate it. This is the sole entry gate — everything |
| 179 | // past this point operates on a path EnterWorktree created. |
| 180 | const session = getCurrentWorktreeSession() |
| 181 | if (!session) { |
| 182 | return { |
| 183 | result: false, |
| 184 | message: |
| 185 | 'No-op: there is no active EnterWorktree session to exit. This tool only operates on worktrees created by EnterWorktree in the current session — it will not touch worktrees created manually or in a previous session. No filesystem changes were made.', |
| 186 | errorCode: 1, |
| 187 | } |
| 188 | } |
| 189 | |
| 190 | if (input.action === 'remove' && !input.discard_changes) { |
| 191 | const summary = await countWorktreeChanges( |
| 192 | session.worktreePath, |
| 193 | session.originalHeadCommit, |
| 194 | ) |
| 195 | if (summary === null) { |
| 196 | return { |
| 197 | result: false, |
| 198 | message: `Could not verify worktree state at ${session.worktreePath}. Refusing to remove without explicit confirmation. Re-invoke with discard_changes: true to proceed — or use action: "keep" to preserve the worktree.`, |
| 199 | errorCode: 3, |
| 200 | } |
| 201 | } |
| 202 | const { changedFiles, commits } = summary |
| 203 | if (changedFiles > 0 || commits > 0) { |
| 204 | const parts: string[] = [] |
| 205 | if (changedFiles > 0) { |
| 206 | parts.push( |
| 207 | `${changedFiles} uncommitted ${changedFiles === 1 ? 'file' : 'files'}`, |
| 208 | ) |
| 209 | } |
| 210 | if (commits > 0) { |
| 211 | parts.push( |
| 212 | `${commits} ${commits === 1 ? 'commit' : 'commits'} on ${session.worktreeBranch ?? 'the worktree branch'}`, |
| 213 | ) |
| 214 | } |
| 215 | return { |
| 216 | result: false, |
| 217 | message: `Worktree has ${parts.join(' and ')}. Removing will discard this work permanently. Confirm with the user, then re-invoke with discard_changes: true — or use action: "keep" to preserve the worktree.`, |
| 218 | errorCode: 2, |
| 219 | } |
| 220 | } |
| 221 | } |
| 222 | |
| 223 | return { result: true } |
| 224 | }, |
| 225 | renderToolUseMessage, |
| 226 | renderToolResultMessage, |
| 227 | async call(input) { |
nothing calls this directly
no test coverage detected