Skip to content

Commit 5404cd1

Browse files
sudo-teeCopilot
andauthored
fix(permissions): fix permission request with sub-agents (#162)
* fix(permissions): fix permission request with sub-agents The permission request seems to have changed it's format I updated the permission handling to support both format This should fix #156 * fix(permission): conditionnal check should exclude new format Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 5d0a967 commit 5404cd1

10 files changed

+38
-6
lines changed

lua/opencode/event_manager.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ local util = require('opencode.util')
5252
--- @field type string
5353
--- @field pattern string|string[]
5454
--- @field sessionID string
55+
--- @field tool? {messageID: string, callID: string}
5556
--- @field messageID string
5657
--- @field callID? string
5758
--- @field title string

lua/opencode/ui/formatter.lua

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -683,8 +683,19 @@ function M._format_tool(output, part)
683683

684684
if
685685
state.current_permission
686-
and state.current_permission.messageID == part.messageID
687-
and state.current_permission.callID == part.callID
686+
and (
687+
(
688+
state.current_permission.tool
689+
and state.current_permission.tool.callID == part.callID
690+
and state.current_permission.tool.messageID == part.messageID
691+
)
692+
---@TODO this is for backward compatibility, remove later
693+
or (
694+
not state.current_permission.tool
695+
and state.current_permission.messageID == part.messageID
696+
and state.current_permission.callID == part.callID
697+
)
698+
)
688699
then
689700
M._handle_permission_request(output, part)
690701
end

lua/opencode/ui/renderer.lua

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ function M.setup_subscriptions(subscribe)
8080
{ 'message.part.updated', M.on_part_updated },
8181
{ 'message.part.removed', M.on_part_removed },
8282
{ 'permission.updated', M.on_permission_updated },
83+
{ 'permission.asked', M.on_permission_updated },
8384
{ 'permission.replied', M.on_permission_replied },
8485
{ 'file.edited', M.on_file_edited },
8586
{ 'custom.restore_point.created', M.on_restore_points },
@@ -768,7 +769,13 @@ end
768769
---Re-renders part that requires permission
769770
---@param permission OpencodePermission Event properties
770771
function M.on_permission_updated(permission)
771-
if not permission or not permission.messageID or not permission.callID then
772+
local tool = permission.tool
773+
774+
---@TODO this is for backward compatibility, remove later
775+
local callID = tool and tool.callID or permission.callID
776+
local messageID = tool and tool.messageID or permission.messageID
777+
778+
if not permission or not messageID or not callID then
772779
return
773780
end
774781

@@ -782,9 +789,10 @@ function M.on_permission_updated(permission)
782789

783790
state.current_permission = permission
784791

785-
local part_id = M._find_part_by_call_id(permission.callID, permission.messageID)
792+
local part_id = M._find_part_by_call_id(callID, messageID)
786793
if part_id then
787794
M._rerender_part(part_id)
795+
M.scroll_to_bottom()
788796
end
789797
end
790798

@@ -799,8 +807,13 @@ function M.on_permission_replied(properties)
799807
local old_permission = state.current_permission
800808
state.current_permission = nil
801809

802-
if old_permission and old_permission.callID then
803-
local part_id = M._find_part_by_call_id(old_permission.callID, old_permission.messageID)
810+
---@TODO this is for backward compatibility, remove later
811+
local tool = old_permission and old_permission.tool
812+
local callID = tool and tool.callID or (old_permission and old_permission.callID)
813+
local messageID = tool and tool.messageID or (old_permission and old_permission.messageID)
814+
815+
if old_permission and messageID and callID then
816+
local part_id = M._find_part_by_call_id(callID, messageID)
804817
if part_id then
805818
M._rerender_part(part_id)
806819
end
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"extmarks":[[1,1,0,{"ns_id":3,"virt_text":[["▌󰭻 ","OpencodeMessageRoleUser"],[" "],["USER","OpencodeMessageRoleUser"],["","OpencodeHint"],[" (2026-01-05 14:07:54)","OpencodeHint"],[" [msg_b8e7c60a2001Kisjwk2mVB4dye]","OpencodeHint"]],"right_gravity":true,"priority":10,"virt_text_repeat_linebreak":false,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-3}],[2,2,0,{"ns_id":3,"virt_text":[["▌","OpencodeMessageRoleUser"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-3}],[3,3,0,{"ns_id":3,"virt_text":[["▌","OpencodeMessageRoleUser"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-3}],[4,4,0,{"ns_id":3,"virt_text":[["▌","OpencodeMessageRoleUser"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-3}],[5,5,0,{"ns_id":3,"virt_text":[["▌","OpencodeMessageRoleUser"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-3}],[6,6,0,{"ns_id":3,"virt_text":[["▌","OpencodeMessageRoleUser"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-3}],[7,7,0,{"ns_id":3,"virt_text":[["▌","OpencodeMessageRoleUser"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-3}],[8,8,0,{"ns_id":3,"virt_text":[["▌","OpencodeMessageRoleUser"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-3}],[9,10,0,{"ns_id":3,"virt_text":[[" ","OpencodeMessageRoleAssistant"],[" "],["BUILD","OpencodeMessageRoleAssistant"],[" gpt-4.1","OpencodeHint"],[" (2026-01-05 14:07:54)","OpencodeHint"],[" [msg_b8e7c60f1001aEWYlAaDRXQ4aJ]","OpencodeHint"]],"right_gravity":true,"priority":10,"virt_text_repeat_linebreak":false,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-3}],[10,12,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[11,13,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[12,14,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[13,15,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[14,16,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[15,17,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[16,18,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[17,19,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[18,20,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[19,21,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[20,22,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[21,23,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[22,24,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[23,25,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[24,26,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[25,27,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[26,28,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[27,29,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[28,30,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[29,31,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[30,32,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[31,33,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[32,34,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[33,39,0,{"ns_id":3,"virt_text":[[" ","OpencodeMessageRoleAssistant"],[" "],["BUILD","OpencodeMessageRoleAssistant"],[" gpt-4.1","OpencodeHint"],[" (2026-01-05 14:08:26)","OpencodeHint"],[" [msg_b8e7cde9e0013hRkUyt0X2yMil]","OpencodeHint"]],"right_gravity":true,"priority":10,"virt_text_repeat_linebreak":false,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-3}]],"timestamp":1767622324,"lines":["----","","","@no-trust run a git status and tell me what files are changed","","[lua/opencode/ui/formatter.lua](lua/opencode/ui/formatter.lua)","","**Diagnostics:**  (11)","","----","","","** run** `Shows working tree status`","","`````bash","> git status","","On branch main","Your branch is up to date with 'origin/main'.","","Changes not staged for commit:"," (use \"git add <file>...\" to update what will be committed)"," (use \"git restore <file>...\" to discard changes in working directory)","\tmodified: lua/opencode/event_manager.lua","\tmodified: lua/opencode/ui/formatter.lua","\tmodified: lua/opencode/ui/renderer.lua","","Untracked files:"," (use \"git add <file>...\" to include in what will be committed)","\ttest.lua","\ttests/data/permission_ask_new.json","","no changes added to commit (use \"git add\" and/or \"git commit -a\")","","`````","","**󰻛 Created Snapshot** `5ba6e957`","","----","","","Here are the files that have been changed according to git status:","","- Modified (but not staged):"," - `lua/opencode/event_manager.lua`"," - `lua/opencode/ui/formatter.lua`"," - `lua/opencode/ui/renderer.lua`","","- Untracked files:"," - `test.lua`"," - `tests/data/permission_ask_new.json`","","No files are currently staged for commit. Let me know if you want more details (like the diff), want to stage/commit, or need help with anything else!","",""],"actions":[{"args":["5ba6e95774829e7f501299039b72b72dc32c6620"],"text":"[R]evert file","range":{"to":36,"from":36},"key":"R","display_line":36,"type":"diff_revert_selected_file"},{"args":["5ba6e95774829e7f501299039b72b72dc32c6620"],"text":"Revert [A]ll","range":{"to":36,"from":36},"key":"A","display_line":36,"type":"diff_revert_all"},{"args":["5ba6e95774829e7f501299039b72b72dc32c6620"],"text":"[D]iff","range":{"to":36,"from":36},"key":"D","display_line":36,"type":"diff_open"}]}

tests/data/permission-ask-new-approve.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"extmarks":[[1,1,0,{"ns_id":3,"virt_text":[["▌󰭻 ","OpencodeMessageRoleUser"],[" "],["USER","OpencodeMessageRoleUser"],["","OpencodeHint"],[" (2026-01-05 14:09:08)","OpencodeHint"],[" [msg_b8e7d8222001ZAc4G1t5RfHzou]","OpencodeHint"]],"right_gravity":true,"priority":10,"virt_text_repeat_linebreak":false,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-3}],[2,2,0,{"ns_id":3,"virt_text":[["▌","OpencodeMessageRoleUser"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-3}],[3,3,0,{"ns_id":3,"virt_text":[["▌","OpencodeMessageRoleUser"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-3}],[4,4,0,{"ns_id":3,"virt_text":[["▌","OpencodeMessageRoleUser"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-3}],[5,5,0,{"ns_id":3,"virt_text":[["▌","OpencodeMessageRoleUser"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-3}],[6,8,0,{"ns_id":3,"virt_text":[[" ","OpencodeMessageRoleAssistant"],[" "],["BUILD","OpencodeMessageRoleAssistant"],[" gpt-4.1","OpencodeHint"],[" (2026-01-05 14:09:08)","OpencodeHint"],[" [msg_b8e7d823f001HX1Rr9DYE7TYBf]","OpencodeHint"]],"right_gravity":true,"priority":10,"virt_text_repeat_linebreak":false,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-3}],[7,10,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[8,11,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[9,12,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[10,13,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[11,14,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[12,15,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[13,16,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}],[14,17,0,{"ns_id":3,"virt_text":[["▌","OpencodeToolBorder"]],"right_gravity":true,"priority":4096,"virt_text_repeat_linebreak":true,"virt_text_pos":"win_col","virt_text_hide":false,"virt_text_win_col":-1}]],"timestamp":1767622360,"lines":["----","","","@no-trust run a git status and tell me what files are changed","","[lua/opencode/ui/formatter.lua](lua/opencode/ui/formatter.lua)","","----","","","** run** `Shows working tree status`","","`````bash","> git status","","`````","","> [!ERROR] Error: The user rejected permission to use this specific tool call.","",""],"actions":[]}

tests/data/permission-ask-new-deny.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)