import { z } from 'zod'; import type { ToolDef, ToolContext } from './types.js'; import { rewindOne } from '../pending_changes.js'; const RewindInput = z.object({ change_id: z.string().uuid().optional(), all: z.boolean().optional(), }); type RewindInputT = z.infer; export const rewindTool: ToolDef = { name: 'rewind', description: 'Revert applied changes. Provide change_id to revert a specific change, ' + 'or set all=true to revert all applied changes for the session (in reverse order).', inputSchema: RewindInput, jsonSchema: { type: 'function', function: { name: 'rewind', description: 'Revert applied changes. Provide change_id to revert a specific change, ' + 'or set all=true to revert all applied changes for the session (in reverse order).', parameters: { type: 'object', properties: { change_id: { type: 'string', format: 'uuid', description: 'ID of a specific change to revert' }, all: { type: 'boolean', description: 'If true, revert all applied changes for this session' }, }, required: [], }, }, }, async execute(input: RewindInputT, projectRoot: string, context: ToolContext): Promise { if (input.change_id) { const result = await rewindOne(context.sql, input.change_id, projectRoot); return { results: [result], message: result.success ? `Reverted change ${input.change_id} (${result.operation} on ${result.file_path}).` : `Failed to revert: ${result.error}`, }; } if (input.all) { // Rewind all applied changes for this session in reverse order const applied = await context.sql<{ id: string }[]>` SELECT id FROM pending_changes WHERE session_id = ${context.sessionId} AND status = 'applied' ORDER BY created_at DESC `; const results = []; for (const row of applied) { results.push(await rewindOne(context.sql, row.id, projectRoot)); } const succeeded = results.filter((r) => r.success).length; return { total: results.length, succeeded, failed: results.length - succeeded, results, message: results.length === 0 ? 'No applied changes to revert.' : `Reverted ${succeeded}/${results.length} changes.`, }; } return { error: 'Provide either change_id or all=true.' }; }, };