feat: write/edit robustness — fuzzy patch applier + worktree checkpoints (v2.7.1)
#3 Fuzzy patch applier: new pure fuzzy-match.ts (locateMatch, exact→trim→ unicode-canon→Levenshtein≥0.66, refuse-on-ambiguous) wired into pending_changes applyOne/rewindOne so local-model whitespace/unicode drift in old_string no longer loses the edit. #4 Worktree checkpoint + conversation-trim: checkpoints table + checkpoints.ts (shadow-commit of tracked+untracked into refs/boocode/checkpoints, hooked into the 3 external-agent dispatcher paths) + POST restore route (reset --hard + clean -fd -> transcript trim -> backend-session reset) + "Restore to here" UI. Built by 3 parallel agents; DB-integration testing caught a created_at self-deletion bug. Coder suite 234 passing; server+coder build + web tsc clean. Builds on v2.7.0-mit. openspec write-edit-robustness. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -36,6 +36,24 @@ export interface AgentSessionInfo {
|
||||
last_active_at: string | null;
|
||||
}
|
||||
|
||||
// write-edit-robustness #4: a pre-turn worktree snapshot anchored to an
|
||||
// assistant message. Returned by GET .../checkpoints; drives the per-message
|
||||
// "Restore to here" affordance in CoderMessageList.
|
||||
export interface CoderCheckpoint {
|
||||
id: string;
|
||||
message_id: string;
|
||||
created_at: string;
|
||||
label: string | null;
|
||||
}
|
||||
|
||||
// write-edit-robustness #4: result of POST .../checkpoints/:id/restore.
|
||||
export interface CoderRestoreResult {
|
||||
checkpoint_id: string;
|
||||
messages_deleted: number;
|
||||
worktree_reset: boolean;
|
||||
backend_reset: boolean;
|
||||
}
|
||||
|
||||
export class ApiError extends Error {
|
||||
constructor(
|
||||
public status: number,
|
||||
@@ -407,6 +425,22 @@ export const api = {
|
||||
...(config?.thinking_option_id ? { thinking_option_id: config.thinking_option_id } : {}),
|
||||
}),
|
||||
}),
|
||||
// write-edit-robustness #4: worktree checkpoints. List which assistant
|
||||
// messages in a chat have a pre-turn worktree snapshot ("Restore to here"
|
||||
// is offered only on those). Proxied to boocoder.
|
||||
getCheckpoints: (sessionId: string, chatId: string) =>
|
||||
request<{ checkpoints: CoderCheckpoint[] }>(
|
||||
`/api/coder/sessions/${sessionId}/checkpoints?chat_id=${encodeURIComponent(chatId)}`,
|
||||
),
|
||||
// write-edit-robustness #4: reset the worktree to a checkpoint, trim the
|
||||
// transcript past its anchor message, and reset the agent backend. After it
|
||||
// returns, the caller refetches messages (+ checkpoints) so the trimmed
|
||||
// transcript shows.
|
||||
restoreCheckpoint: (sessionId: string, checkpointId: string) =>
|
||||
request<CoderRestoreResult>(
|
||||
`/api/coder/sessions/${sessionId}/checkpoints/${encodeURIComponent(checkpointId)}/restore`,
|
||||
{ method: 'POST' },
|
||||
),
|
||||
// Queue a new-file create from the RightRail browser → BooCoder
|
||||
// pending_changes (operation='create'). Surfaces in the CoderPane DiffPanel
|
||||
// for explicit apply. A WriteGuardError comes back as a 422 whose { error }
|
||||
|
||||
Reference in New Issue
Block a user