fix(ui): track worktree context for question replies

Store the originating worktree slug when questions are enqueued and use
the stored worktree client when replying/rejecting from the global
permission center. This ensures question responses are sent through the
correct worktree, matching the behavior already implemented for
permissions.
This commit is contained in:
Shantur Rathore
2026-02-18 19:56:42 +00:00
parent f75c942162
commit b4121696bb

View File

@@ -52,6 +52,8 @@ const permissionSessionCounts = new Map<string, Map<string, number>>()
const permissionWorktreeSlugByInstance = new Map<string, Map<string, string>>() const permissionWorktreeSlugByInstance = new Map<string, Map<string, string>>()
const [questionQueues, setQuestionQueues] = createSignal<Map<string, QuestionRequest[]>>(new Map()) const [questionQueues, setQuestionQueues] = createSignal<Map<string, QuestionRequest[]>>(new Map())
// Track which worktree a question was enqueued under (by question request id).
const questionWorktreeSlugByInstance = new Map<string, Map<string, string>>()
const [activeQuestionId, setActiveQuestionId] = createSignal<Map<string, string | null>>(new Map()) const [activeQuestionId, setActiveQuestionId] = createSignal<Map<string, string | null>>(new Map())
const questionSessionCounts = new Map<string, Map<string, number>>() const questionSessionCounts = new Map<string, Map<string, number>>()
const questionEnqueuedAt = new Map<string, number>() const questionEnqueuedAt = new Map<string, number>()
@@ -877,6 +879,16 @@ function addQuestionToQueue(instanceId: string, request: QuestionRequest): void
if (sessionId) { if (sessionId) {
incrementQuestionSessionPendingCount(instanceId, sessionId) incrementQuestionSessionPendingCount(instanceId, sessionId)
setSessionPendingQuestion(instanceId, sessionId, true) setSessionPendingQuestion(instanceId, sessionId, true)
// Record the worktree slug at the time the question is enqueued.
// This is used to respond in the same worktree context even from the global permission center.
const slug = getWorktreeSlugForSession(instanceId, sessionId)
let byQuestionId = questionWorktreeSlugByInstance.get(instanceId)
if (!byQuestionId) {
byQuestionId = new Map()
questionWorktreeSlugByInstance.set(instanceId, byQuestionId)
}
byQuestionId.set(request.id, slug)
} }
} }
@@ -897,6 +909,7 @@ function removeQuestionFromQueue(instanceId: string, requestId: string): void {
}) })
questionEnqueuedAt.delete(requestId) questionEnqueuedAt.delete(requestId)
questionWorktreeSlugByInstance.get(instanceId)?.delete(requestId)
recomputeActiveInterruption(instanceId) recomputeActiveInterruption(instanceId)
if (removedSessionId) { if (removedSessionId) {
@@ -909,6 +922,7 @@ function clearQuestionQueue(instanceId: string): void {
for (const request of getQuestionQueue(instanceId)) { for (const request of getQuestionQueue(instanceId)) {
questionEnqueuedAt.delete(request.id) questionEnqueuedAt.delete(request.id)
} }
questionWorktreeSlugByInstance.delete(instanceId)
setQuestionQueues((prev) => { setQuestionQueues((prev) => {
const next = new Map(prev) const next = new Map(prev)
@@ -934,7 +948,7 @@ function setActiveQuestionIdForInstance(instanceId: string, requestId: string):
async function sendQuestionReply( async function sendQuestionReply(
instanceId: string, instanceId: string,
_sessionId: string, sessionId: string,
requestId: string, requestId: string,
answers: string[][], answers: string[][],
): Promise<void> { ): Promise<void> {
@@ -944,8 +958,13 @@ async function sendQuestionReply(
} }
try { try {
const stored = questionWorktreeSlugByInstance.get(instanceId)?.get(requestId)
const fallback = sessionId ? getWorktreeSlugForSession(instanceId, sessionId) : "root"
const worktreeSlug = stored ?? fallback
const client = getOrCreateWorktreeClient(instanceId, worktreeSlug)
await requestData( await requestData(
instance.client.question.reply({ client.question.reply({
requestID: requestId, requestID: requestId,
answers, answers,
}), }),
@@ -959,15 +978,20 @@ async function sendQuestionReply(
} }
} }
async function sendQuestionReject(instanceId: string, _sessionId: string, requestId: string): Promise<void> { async function sendQuestionReject(instanceId: string, sessionId: string, requestId: string): Promise<void> {
const instance = instances().get(instanceId) const instance = instances().get(instanceId)
if (!instance?.client) { if (!instance?.client) {
throw new Error("Instance not ready") throw new Error("Instance not ready")
} }
try { try {
const stored = questionWorktreeSlugByInstance.get(instanceId)?.get(requestId)
const fallback = sessionId ? getWorktreeSlugForSession(instanceId, sessionId) : "root"
const worktreeSlug = stored ?? fallback
const client = getOrCreateWorktreeClient(instanceId, worktreeSlug)
await requestData( await requestData(
instance.client.question.reject({ client.question.reject({
requestID: requestId, requestID: requestId,
}), }),
"question.reject", "question.reject",