feature: ability to rewind #241

Closed
opened 2026-02-16 17:25:53 -05:00 by yindo · 12 comments
Owner

Originally created by @codetorex on GitHub (Jun 23, 2025).

Originally assigned to: @adamdotdevin on GitHub.

When working with AI tools, they occasionally wander off in a direction we don't want or get stuck in a loop that requires additional input or guidance.

It would be great if we could rewind the state as much as needed. This would roll back file changes and messages to a previous point in time. Ideally, we could choose how far to rewind using the keyboard or something similar, then provide additional input and let the AI explore possible solutions again.

This feature would be especially helpful for optimizing context usage and reducing input costs by avoiding unnecessary or repetitive queries.

Possible implementation considerations:

  • Initially, when rolling files back, it might be possible to rely on rolling back write tool usage. However, sometimes LLMs batch replace content in files using tools like sed, so a more advanced solution may be needed.
  • A possible solution is relying on Git.
    • An issue is that this might clutter the user's Git usage.
    • We could get the list of changed files and keep an entire copy of them in a database.
      • One problem with this is that the project folder might not be using Git at all. In that case, we could disable the rewind feature or only allow rewinding write tool usages.
  • UX could be like pressing Ctrl+Shift+R or something similar to enter rewind mode, then using the up and down arrow keys to navigate backward and forward through the history. The output could be grayed out while navigating, with Enter to roll back to the selected point in time or Esc to exit rewind mode and return to normal operation.

On the previous v0.0.52 version, I was manually editing the SQLite database, rolling back files using Git, and restarting the app to reload the context.

Is there any interest in this, or is my workflow just very bad? :)

Originally created by @codetorex on GitHub (Jun 23, 2025). Originally assigned to: @adamdotdevin on GitHub. When working with AI tools, they occasionally wander off in a direction we don't want or get stuck in a loop that requires additional input or guidance. It would be great if we could rewind the state as much as needed. This would roll back file changes and messages to a previous point in time. Ideally, we could choose how far to rewind using the keyboard or something similar, then provide additional input and let the AI explore possible solutions again. This feature would be especially helpful for optimizing context usage and reducing input costs by avoiding unnecessary or repetitive queries. Possible implementation considerations: - Initially, when rolling files back, it might be possible to rely on rolling back write tool usage. However, sometimes LLMs batch replace content in files using tools like `sed`, so a more advanced solution may be needed. - A possible solution is relying on Git. - An issue is that this might clutter the user's Git usage. - We could get the list of changed files and keep an entire copy of them in a database. - One problem with this is that the project folder might not be using Git at all. In that case, we could disable the rewind feature or only allow rewinding write tool usages. - UX could be like pressing `Ctrl+Shift+R` or something similar to enter rewind mode, then using the up and down arrow keys to navigate backward and forward through the history. The output could be grayed out while navigating, with `Enter` to roll back to the selected point in time or `Esc` to exit rewind mode and return to normal operation. On the previous v0.0.52 version, I was manually editing the SQLite database, rolling back files using Git, and restarting the app to reload the context. Is there any interest in this, or is my workflow just very bad? :)
yindo added the growth label 2026-02-16 17:25:53 -05:00
yindo closed this issue 2026-02-16 17:25:53 -05:00
Author
Owner

@khalido commented on GitHub (Jun 25, 2025):

fyi, the new Gemini cli handles this with a shadow git folder: https://github.com/google-gemini/gemini-cli/blob/main/docs/checkpointing.md

  1. A Git Snapshot: A commit is made in a special, shadow Git repository located in your home directory (~/.gemini/history/<project_hash>). This snapshot captures the complete state of your project files at that moment. It does not interfere with your own project's Git repository.
  1. Conversation History: The entire conversation you've had with the agent up to that point is saved.
  1. The Tool Call: The specific tool call that was about to be executed is also stored.
@khalido commented on GitHub (Jun 25, 2025): fyi, the new Gemini cli handles this with a shadow git folder: https://github.com/google-gemini/gemini-cli/blob/main/docs/checkpointing.md > 1. A Git Snapshot: A commit is made in a special, shadow Git repository located in your home directory (~/.gemini/history/<project_hash>). This snapshot captures the complete state of your project files at that moment. It does not interfere with your own project's Git repository. > 2. Conversation History: The entire conversation you've had with the agent up to that point is saved. > 3. The Tool Call: The specific tool call that was about to be executed is also stored.
Author
Owner

@codetorex commented on GitHub (Jun 25, 2025):

fyi, the new Gemini cli handles this with a shadow git folder: https://github.com/google-gemini/gemini-cli/blob/main/docs/checkpointing.md

  1. A Git Snapshot: A commit is made in a special, shadow Git repository located in your home directory (~/.gemini/history/<project_hash>). This snapshot captures the complete state of your project files at that moment. It does not interfere with your own project's Git repository.
  1. Conversation History: The entire conversation you've had with the agent up to that point is saved.
  1. The Tool Call: The specific tool call that was about to be executed is also stored.

Hmm, interesting. Though I don’t like the idea of storing data in the home directory, especially under a hash that is meaningless to humans. Anything related to the project should be kept in the project folder. Something like /.opencode/history would be a far better option, in my opinion.

@codetorex commented on GitHub (Jun 25, 2025): > fyi, the new Gemini cli handles this with a shadow git folder: https://github.com/google-gemini/gemini-cli/blob/main/docs/checkpointing.md > > > 1. A Git Snapshot: A commit is made in a special, shadow Git repository located in your home directory (~/.gemini/history/<project_hash>). This snapshot captures the complete state of your project files at that moment. It does not interfere with your own project's Git repository. > > > 2. Conversation History: The entire conversation you've had with the agent up to that point is saved. > > > 3. The Tool Call: The specific tool call that was about to be executed is also stored. Hmm, interesting. Though I don’t like the idea of storing data in the home directory, especially under a hash that is meaningless to humans. Anything related to the project should be kept in the project folder. Something like <project folder>/.opencode/history would be a far better option, in my opinion.
Author
Owner

@InsightfulFuture commented on GitHub (Jul 12, 2025):

+1, especially if restoring allows you to edit past messages

@InsightfulFuture commented on GitHub (Jul 12, 2025): +1, especially if restoring allows you to edit past messages
Author
Owner

@SerialVelocity commented on GitHub (Jul 24, 2025):

Ideally, it would be possible to also just to rollback the chat without also rewinding file changes. This is quite useful when you want to keep previous context, but ended up using lots of the context window just trying to implement something.

I've also used claude code like this when processing files. I can rewind, tell it that folder X has been processed previously, now just process folder Y. Otherwise, I end up hitting the context window limit.

@SerialVelocity commented on GitHub (Jul 24, 2025): Ideally, it would be possible to also just to rollback the chat without also rewinding file changes. This is quite useful when you want to keep previous context, but ended up using lots of the context window just trying to implement something. I've also used claude code like this when processing files. I can rewind, tell it that folder X has been processed previously, now just process folder Y. Otherwise, I end up hitting the context window limit.
Author
Owner

@dikkadev commented on GitHub (Jul 26, 2025):

I like the previous points from this issue! Just another use-case that would be supported with this:

Suppose in a longer conversation the agent just finished a task/feature but it's not quite right (point A). Multiple message iterations are done to fix it in the same chat. It would be most useful to be able to go back to point A to continue the conversation normally but still have the fixes/changes without the tokens used in those messages after point A.

What's really unclear to me is what the UX should be like to do these things. Rollback with file changes and rollback without file changes. Would we also want branching? Probably not at first?

@dikkadev commented on GitHub (Jul 26, 2025): I like the previous points from this issue! Just another use-case that would be supported with this: Suppose in a longer conversation the agent just finished a task/feature but it's not quite right (point A). Multiple message iterations are done to fix it in the same chat. It would be most useful to be able to go back to point A to continue the conversation normally but still have the fixes/changes without the tokens used in those messages after point A. What's really unclear to me is what the UX should be like to do these things. Rollback with file changes and rollback without file changes. Would we also want branching? Probably not at first?
Author
Owner

@SerialVelocity commented on GitHub (Jul 27, 2025):

I think there's probably different milestones to get something like this implemented:

  1. Simple rollback where all file changes are kept (no branching)
  2. Change rollback to create a branch (new conversation)
  3. Second option for rollback where file changes are reverted as well

Main reason for that ordering is that (1) and (2) are easy. They could even be tackled in the same PR most likely, but if it is complex for some reason, it can be split apart.

(3) is probably more difficult because you have to figure out whether to implement this with shadow git repos, or something else.
Open questions for that:

  • What happens if a user has made manual changes, do they get discarded too?
  • Do you support rolling back code changes through MCPs? e.g. what if the LLM decided to use sed, tr, or an inline python script?
  • If it's done with shadow git repos, what happens to untracked files? What about files in the .gitignore, etc
@SerialVelocity commented on GitHub (Jul 27, 2025): I think there's probably different milestones to get something like this implemented: 1. Simple rollback where all file changes are kept (no branching) 2. Change rollback to create a branch (new conversation) 3. Second option for rollback where file changes are reverted as well Main reason for that ordering is that (1) and (2) are easy. They could even be tackled in the same PR most likely, but if it is complex for some reason, it can be split apart. (3) is probably more difficult because you have to figure out whether to implement this with shadow git repos, or something else. Open questions for that: - What happens if a user has made manual changes, do they get discarded too? - Do you support rolling back code changes through MCPs? e.g. what if the LLM decided to use `sed`, `tr`, or an inline `python` script? - If it's done with shadow git repos, what happens to untracked files? What about files in the .gitignore, etc
Author
Owner

@dikkadev commented on GitHub (Jul 30, 2025):

I agree with the milestones split.
(3) probably needs even more questions and answers when it comes to actually doing it and supporting a range of use cases. A separate issue to track those that conversation would probably be good at some point.
But 'just' (1) and (2) would provide use-cases, though they should be made with (3) in mind IMO

@dikkadev commented on GitHub (Jul 30, 2025): I agree with the milestones split. (3) probably needs even more questions and answers when it comes to actually doing it and supporting a range of use cases. A separate issue to track those that conversation would probably be good at some point. But 'just' (1) and (2) would provide use-cases, though they should be made with (3) in mind IMO
Author
Owner

@dikkadev commented on GitHub (Jul 30, 2025):

It's probably good to note that in part this is already implemented over a snapshot sysytem.
https://github.com/sst/opencode/pull/1268
And released, but disabled except in dev mode (?), in https://github.com/sst/opencode/releases/tag/v0.3.61

@dikkadev commented on GitHub (Jul 30, 2025): It's probably good to note that in part this is already implemented over a snapshot sysytem. https://github.com/sst/opencode/pull/1268 And released, but disabled except in dev mode (?), in https://github.com/sst/opencode/releases/tag/v0.3.61
Author
Owner

@nerdo commented on GitHub (Aug 2, 2025):

this may seem like a workaround, but i've been using it with pretty good results in claude code.

i use jj and colocate my repos with git. tldr: i don't let claude make changes with git but I give it pretty broad permissions with jj.

the result is that it can use version control locally to handle creating milestones, describing changes, etc. and claude code doesn't need to be concerned with how it happens. version control is incredibly complex, and that's effectively what I think this discussion is about.

@nerdo commented on GitHub (Aug 2, 2025): this may seem like a workaround, but i've been using it with pretty good results in claude code. i use jj and colocate my repos with git. tldr: i don't let claude make changes with git but I give it pretty broad permissions with jj. the result is that it can use version control locally to handle creating milestones, describing changes, etc. and claude code doesn't need to be concerned with how it happens. version control is incredibly complex, and that's effectively what I think this discussion is about.
Author
Owner

@rekram1-node commented on GitHub (Aug 28, 2025):

checkpointing support was added, with redo & undo

@rekram1-node commented on GitHub (Aug 28, 2025): checkpointing support was added, with redo & undo
Author
Owner

@Enelass commented on GitHub (Feb 3, 2026):

The /timeline command claims to offer rewind functionality but fails to deliver. It displays a message suggesting it can restore previous states, yet nothing actually happens.

OpenCode is missing a critical feature that most CLI tools provide as standard: a functioning /rewind capability. This is not just inconvenient, it's dangerous. Users who discover that the advertised rewind feature doesn't actually work are left exposed to potential data loss. By the time you realise the safety net isn't there, it's already too late.

Image
@Enelass commented on GitHub (Feb 3, 2026): The `/timeline` command claims to offer rewind functionality but fails to deliver. It displays a message suggesting it can restore previous states, yet nothing actually happens. OpenCode is missing a critical feature that most CLI tools provide as standard: a functioning `/rewind` capability. This is not just inconvenient, it's dangerous. Users who discover that the advertised rewind feature doesn't actually work are left exposed to potential data loss. By the time you realise the safety net isn't there, it's already too late. <img width="262" height="99" alt="Image" src="https://github.com/user-attachments/assets/b6e061ea-4e13-42cf-a0b6-9ffe30184887" />
Author
Owner

@Enelass commented on GitHub (Feb 3, 2026):

This issue should be re-opened

@Enelass commented on GitHub (Feb 3, 2026): This issue should be re-opened
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#241