Rewind chat or files from any user message (#1154)

* Add Pi extension-launch plumbing for in-process tree primitives

* Add Rewind controls for agent sessions

* Preserve SDK checkpoint env var so Claude file rewind works

The SDK injects CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING=true when file checkpointing is enabled. The earlier parent-env stripping from c4782ec71c was too broad and removed that child flag along with real parent-session markers.

Keep stripping parent markers, but preserve the checkpoint flag so the SDK rewind path can run directly. With that boundary fixed, the JSONL file-rewind fallback is no longer needed.

* Update OpenCode history replay tests for rewind state

* Show Rewind actions in an adaptive sheet

* Fix rewind semantics across providers

* Refactor Pi IDs through extension capture

* Restore user message to composer after rewind

* Fix Claude rewind tool result mapping

* Fix Claude rewind session switch roundtrip

* Fix rewind and optimistic message regressions

* Tighten rewind test discipline

* Fix OpenCode optimistic message reconciliation

* Reconcile optimistic user messages by marker

* Reorder user message actions

* Unify provider user message contract

* Add Claude rewind flow Playwright contract

* Add Codex rewind flow Playwright contract

* Add OpenCode rewind flow Playwright contract

* Add Pi rewind flow Playwright contract

* Remove real-provider rewind Playwright contracts

* Gate real-provider rewind specs from CI Playwright
This commit is contained in:
Mohamed Boudra
2026-05-25 17:11:34 +08:00
committed by GitHub
parent e966f70322
commit 132e572d6e
99 changed files with 7106 additions and 3425 deletions
@@ -0,0 +1,36 @@
import { describe, expect, test } from "vitest";
import { resolveRewindMenuItems } from "./use-rewind-capabilities";
describe("resolveRewindMenuItems", () => {
test("returns no items when the provider declares no rewind capability", () => {
expect(
resolveRewindMenuItems({
supportsRewindConversation: false,
supportsRewindFiles: false,
supportsRewindBoth: false,
}),
).toEqual([]);
});
test("returns only the capabilities declared by the provider", () => {
expect(
resolveRewindMenuItems({
supportsRewindConversation: true,
supportsRewindFiles: false,
supportsRewindBoth: true,
}),
).toEqual([
{
mode: "conversation",
label: "Rewind conversation",
testID: "rewind-menu-conversation",
},
{
mode: "both",
label: "Rewind conversation and files",
testID: "rewind-menu-both",
},
]);
});
});