summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAiden Cline <[email protected]>2025-09-07 21:45:13 -0500
committerGitHub <[email protected]>2025-09-07 21:45:13 -0500
commit74469a0d3da4f143f7c199d3c3ef27cbd63d8536 (patch)
treeb9f82ae1098bdf79283bed58e1ae71c967c155b6
parent4d481dea7ee744f7ddfb29d6b299fa4ecb79dab5 (diff)
downloadopencode-74469a0d3da4f143f7c199d3c3ef27cbd63d8536.tar.gz
opencode-74469a0d3da4f143f7c199d3c3ef27cbd63d8536.zip
fix: shell invocations are dropped if last interaction was revert (#2485)
-rw-r--r--packages/opencode/src/session/index.ts60
1 files changed, 35 insertions, 25 deletions
diff --git a/packages/opencode/src/session/index.ts b/packages/opencode/src/session/index.ts
index 113cf67bf..2b49bb74a 100644
--- a/packages/opencode/src/session/index.ts
+++ b/packages/opencode/src/session/index.ts
@@ -365,6 +365,36 @@ export namespace Session {
return part
}
+ async function cleanupRevert(session: Info) {
+ if (!session.revert) return
+ const sessionID = session.id
+ let msgs = await messages(sessionID)
+ const messageID = session.revert.messageID
+ const [preserve, remove] = splitWhen(msgs, (x) => x.info.id === messageID)
+ msgs = preserve
+ for (const msg of remove) {
+ await Storage.remove(["message", sessionID, msg.info.id])
+ await Bus.publish(MessageV2.Event.Removed, { sessionID: sessionID, messageID: msg.info.id })
+ }
+ const last = preserve.at(-1)
+ if (session.revert.partID && last) {
+ const partID = session.revert.partID
+ const [preserveParts, removeParts] = splitWhen(last.parts, (x) => x.id === partID)
+ last.parts = preserveParts
+ for (const part of removeParts) {
+ await Storage.remove(["part", last.info.id, part.id])
+ await Bus.publish(MessageV2.Event.PartRemoved, {
+ sessionID: sessionID,
+ messageID: last.info.id,
+ partID: part.id,
+ })
+ }
+ }
+ await update(sessionID, (draft) => {
+ draft.revert = undefined
+ })
+ }
+
export const PromptInput = z.object({
sessionID: Identifier.schema("session"),
messageID: Identifier.schema("message").optional(),
@@ -425,31 +455,7 @@ export namespace Session {
// Process revert cleanup first, before creating new messages
const session = await get(input.sessionID)
if (session.revert) {
- let msgs = await messages(input.sessionID)
- const messageID = session.revert.messageID
- const [preserve, remove] = splitWhen(msgs, (x) => x.info.id === messageID)
- msgs = preserve
- for (const msg of remove) {
- await Storage.remove(["message", input.sessionID, msg.info.id])
- await Bus.publish(MessageV2.Event.Removed, { sessionID: input.sessionID, messageID: msg.info.id })
- }
- const last = preserve.at(-1)
- if (session.revert.partID && last) {
- const partID = session.revert.partID
- const [preserveParts, removeParts] = splitWhen(last.parts, (x) => x.id === partID)
- last.parts = preserveParts
- for (const part of removeParts) {
- await Storage.remove(["part", last.info.id, part.id])
- await Bus.publish(MessageV2.Event.PartRemoved, {
- sessionID: input.sessionID,
- messageID: last.info.id,
- partID: part.id,
- })
- }
- }
- await update(input.sessionID, (draft) => {
- draft.revert = undefined
- })
+ cleanupRevert(session)
}
const userMsg: MessageV2.Info = {
id: input.messageID ?? Identifier.ascending("message"),
@@ -1085,6 +1091,10 @@ export namespace Session {
export type ShellInput = z.infer<typeof ShellInput>
export async function shell(input: ShellInput) {
using abort = lock(input.sessionID)
+ const session = await get(input.sessionID)
+ if (session.revert) {
+ cleanupRevert(session)
+ }
const userMsg: MessageV2.User = {
id: Identifier.ascending("message"),
sessionID: input.sessionID,