From ca178b65781a8c3a6b3f9c784bed960aa1263bc8 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Mon, 2 Nov 2026 07:20:56 +0100 Subject: [PATCH] fix(plugins): attachment commands honor the composer lock The creation request captures the attachments when it starts, so an attachment a plugin added or removed afterwards was lost or left in the request. They refuse like the prompt commands. --- packages/app/src/plugins/composer-items/model.test.ts | 9 +++++++++ packages/app/src/plugins/composer-items/model.ts | 2 ++ 2 files changed, 11 insertions(+) diff --git a/packages/app/src/plugins/composer-items/model.test.ts b/packages/app/src/plugins/composer-items/model.test.ts index 4e5f3dee18..e75585e36f 100644 --- a/packages/app/src/plugins/composer-items/model.test.ts +++ b/packages/app/src/plugins/composer-items/model.test.ts @@ -205,6 +205,9 @@ describe("toPluginComposer", () => { expect(() => composer.setPrompt("a")).toThrow("The composer is locked"); expect(() => composer.insertText("b")).toThrow("The composer is locked"); + expect(() => composer.addAttachment({ sourceId: "issues", item: issue })).toThrow( + "The composer is locked", + ); await expect(composer.setProvider("codex")).rejects.toThrow("The composer is locked"); await expect(composer.setModel("gpt")).rejects.toThrow("The composer is locked"); await expect(composer.setMode("plan")).rejects.toThrow("The composer is locked"); @@ -231,6 +234,12 @@ describe("toPluginComposer", () => { input.isLocked = () => lock.locked; expect(() => composer.insertText("late")).toThrow("The composer is locked"); + expect(() => composer.addAttachment({ sourceId: "issues", item: issue })).toThrow( + "The composer is locked", + ); + expect(() => composer.removeAttachment({ sourceId: "issues", itemId: issue.id })).toThrow( + "The composer is locked", + ); await expect(composer.setOptions({ effort: "low" })).rejects.toThrow("The composer is locked"); }); diff --git a/packages/app/src/plugins/composer-items/model.ts b/packages/app/src/plugins/composer-items/model.ts index f4c502a996..e2d8f173e7 100644 --- a/packages/app/src/plugins/composer-items/model.ts +++ b/packages/app/src/plugins/composer-items/model.ts @@ -68,6 +68,7 @@ export function toPluginComposer(input: { composerInput.insertText(text); }, addAttachment({ sourceId, item }) { + assertUnlocked(composerInput.isLocked); const source = plugin.attachmentSources.find((candidate) => candidate.id === sourceId); if (!source) throw new Error(`Unknown attachment source: ${sourceId}`); const attachment = createPluginResourceAttachment( @@ -86,6 +87,7 @@ export function toPluginComposer(input: { ); }, removeAttachment({ sourceId, itemId }) { + assertUnlocked(composerInput.isLocked); composerInput.changeAttachments((current) => current.filter((candidate) => !isPluginAttachment(candidate, plugin.id, sourceId, itemId)), );