fix(server): resolve Claude user input prompts on stop - #4096

Closed
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-stale-user-input-gui
Closed

fix(server): resolve Claude user input prompts on stop#4096
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-stale-user-input-gui

Conversation

@nateEc

@nateEcnateEc commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Closes#4060.

Summary

  • Cancel pending Claude AskUserQuestion requests when the provider session stops.
  • Emit user-input.resolved during session stop so projected threads clear stale user-input prompts.
  • Keep SDK permission results as deny/cancel instead of allowing an empty answer payload.

Verification

  • corepack pnpm exec vp test run apps/server/src/provider/Layers/ClaudeAdapter.test.ts
  • corepack pnpm exec vp run typecheck
  • corepack pnpm exec vp check (passes with existing warnings outside this change)

Note

Medium Risk
Touches Claude SDK permission callbacks and session teardown ordering, but behavior is narrowly scoped to user-input lifecycle with broad new tests.

Overview
Fixes stale AskUserQuestion prompts by ensuring pending Claude user-input requests always get a single terminal outcome and the chat UI stops showing them once the provider session is gone.

Claude adapter adds settlePendingUserInput so each prompt is settled exactly once: it waits for user-input.requested before emitting user-input.resolved, handles races (abort vs stopSession vs provider exit), and returns deny with empty answers on cancel instead of allowing the tool. Session teardown (stopSession / stopAll) and abort listeners now route through this helper; duplicate respondToUserInput calls fail with ProviderAdapterRequestError; canUseTool denies when the session is missing or already stopped.

Web passes session status into derivePendingUserInputs so prompts are hidden when status is stopped, including legacy threads that never got a resolved event.

Reviewed by Cursor Bugbot for commit e8dc20d. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Resolve pending Claude AskUserQuestion prompts when a session stops

  • When a Claude session stops, all pending AskUserQuestion requests are now cancelled and emit a user-input.resolved event with empty answers and a deny result of 'User cancelled tool execution.'
  • A new settlePendingUserInput helper in ClaudeAdapter.ts ensures each request resolves exactly once, ordering the resolved event after the corresponding requested event.
  • canUseTool and handleAskUserQuestion now immediately deny with 'Claude session context is unavailable or stopped.' when called after session stop or with an already-aborted signal.
  • Duplicate respondToUserInput calls for the same request now return a ProviderAdapterRequestError instead of silently succeeding.
  • derivePendingUserInputs in session-logic.ts returns an empty list when session status is 'stopped', clearing stale prompts from the UI.

Macroscope summarized e8dc20d.

@coderabbitai

coderabbitaiBot commented Jul 17, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 0a9b1d75-6b94-42d7-965c-a2c8fab498f7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Jul 17, 2026
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts Outdated
@macroscopeapp

macroscopeappBot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces significant runtime behavior changes for handling pending user input prompts when Claude sessions stop, including new concurrency handling logic for race conditions. An unresolved review comment identifies inconsistent deny messages between abort and session-stop paths.

You can customize Macroscope's approvability policy. Learn more.

PR: pingdotgg#4096
Co-authored-by: codex <codex@users.noreply.github.com>
@juliusmarminge
juliusmarmingeforce-pushed the codex/fix-stale-user-input-gui branch from f7f07cf to 47aa733CompareJuly 20, 2026 17:11
@github-actionsgithub-actionsBot added size:L 100-499 changed lines (additions + deletions). and removed size:M 30-99 changed lines (additions + deletions). labels Jul 20, 2026
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts
- 在请求发布与注册之间建立不可中断的生命周期边界,停止后不再新增待处理输入。
- resolved 发布完成后再移除请求,并确保所有竞态等待者都会被释放。
- 增加停止后回调回归测试,并通过并发测试、vp check 与类型检查。

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit e8dc20d. Configure here.

return {
behavior: "deny",
message: "Claude session context is unavailable or stopped.",
} satisfies PermissionResult;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Abort deny uses stopped message

Medium Severity

Registration treats an already-aborted signal the same as a stopped session and returns deny with Claude session context is unavailable or stopped. That path never settles as cancelled, so the SDK sees a session-dead reason instead of the usual User cancelled tool execution. cancel deny when only the tool call was aborted.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit e8dc20d. Configure here.

@juliusmarminge

Copy link
Copy Markdown
Member

Closing in favor of #2829 (orchestration V2).

#2829 deletes the V1 orchestration layer this PR builds on — apps/server/src/orchestration/**, provider/Layers/*Adapter.ts and provider/Services/** are removed and replaced by apps/server/src/orchestration-v2/**, with the IPC surface renamed to ORCHESTRATION_V2_WS_METHODS. The files this PR touches either no longer exist or are rewritten, so it can't be rebased — it would need reimplementing against the V2 adapters.

This is not a judgement on the change itself. Several of these are real gaps we still want fixed; the base just moved out from under them.

Once #2829 merges, please rebase onto main, port the change to the V2 equivalent, and reopen (or open a fresh PR). Ping me and I'll prioritise the review.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Stuck on User Input Tool GUI

2 participants

@nateEc@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix(server): resolve Claude user input prompts on stop - #4096

Closed
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-stale-user-input-gui
Closed

fix(server): resolve Claude user input prompts on stop#4096
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-stale-user-input-gui

Conversation

@nateEc

@nateEcnateEc commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Closes#4060.

Summary

  • Cancel pending Claude AskUserQuestion requests when the provider session stops.
  • Emit user-input.resolved during session stop so projected threads clear stale user-input prompts.
  • Keep SDK permission results as deny/cancel instead of allowing an empty answer payload.

Verification

  • corepack pnpm exec vp test run apps/server/src/provider/Layers/ClaudeAdapter.test.ts
  • corepack pnpm exec vp run typecheck
  • corepack pnpm exec vp check (passes with existing warnings outside this change)

Note

Medium Risk
Touches Claude SDK permission callbacks and session teardown ordering, but behavior is narrowly scoped to user-input lifecycle with broad new tests.

Overview
Fixes stale AskUserQuestion prompts by ensuring pending Claude user-input requests always get a single terminal outcome and the chat UI stops showing them once the provider session is gone.

Claude adapter adds settlePendingUserInput so each prompt is settled exactly once: it waits for user-input.requested before emitting user-input.resolved, handles races (abort vs stopSession vs provider exit), and returns deny with empty answers on cancel instead of allowing the tool. Session teardown (stopSession / stopAll) and abort listeners now route through this helper; duplicate respondToUserInput calls fail with ProviderAdapterRequestError; canUseTool denies when the session is missing or already stopped.

Web passes session status into derivePendingUserInputs so prompts are hidden when status is stopped, including legacy threads that never got a resolved event.

Reviewed by Cursor Bugbot for commit e8dc20d. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Resolve pending Claude AskUserQuestion prompts when a session stops

  • When a Claude session stops, all pending AskUserQuestion requests are now cancelled and emit a user-input.resolved event with empty answers and a deny result of 'User cancelled tool execution.'
  • A new settlePendingUserInput helper in ClaudeAdapter.ts ensures each request resolves exactly once, ordering the resolved event after the corresponding requested event.
  • canUseTool and handleAskUserQuestion now immediately deny with 'Claude session context is unavailable or stopped.' when called after session stop or with an already-aborted signal.
  • Duplicate respondToUserInput calls for the same request now return a ProviderAdapterRequestError instead of silently succeeding.
  • derivePendingUserInputs in session-logic.ts returns an empty list when session status is 'stopped', clearing stale prompts from the UI.

Macroscope summarized e8dc20d.

@coderabbitai

coderabbitaiBot commented Jul 17, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 0a9b1d75-6b94-42d7-965c-a2c8fab498f7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Jul 17, 2026
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts Outdated
@macroscopeapp

macroscopeappBot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces significant runtime behavior changes for handling pending user input prompts when Claude sessions stop, including new concurrency handling logic for race conditions. An unresolved review comment identifies inconsistent deny messages between abort and session-stop paths.

You can customize Macroscope's approvability policy. Learn more.

PR: pingdotgg#4096
Co-authored-by: codex <codex@users.noreply.github.com>
@juliusmarminge
juliusmarmingeforce-pushed the codex/fix-stale-user-input-gui branch from f7f07cf to 47aa733CompareJuly 20, 2026 17:11
@github-actionsgithub-actionsBot added size:L 100-499 changed lines (additions + deletions). and removed size:M 30-99 changed lines (additions + deletions). labels Jul 20, 2026
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts
- 在请求发布与注册之间建立不可中断的生命周期边界,停止后不再新增待处理输入。
- resolved 发布完成后再移除请求,并确保所有竞态等待者都会被释放。
- 增加停止后回调回归测试,并通过并发测试、vp check 与类型检查。

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit e8dc20d. Configure here.

return {
behavior: "deny",
message: "Claude session context is unavailable or stopped.",
} satisfies PermissionResult;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Abort deny uses stopped message

Medium Severity

Registration treats an already-aborted signal the same as a stopped session and returns deny with Claude session context is unavailable or stopped. That path never settles as cancelled, so the SDK sees a session-dead reason instead of the usual User cancelled tool execution. cancel deny when only the tool call was aborted.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit e8dc20d. Configure here.

@juliusmarminge

Copy link
Copy Markdown
Member

Closing in favor of #2829 (orchestration V2).

#2829 deletes the V1 orchestration layer this PR builds on — apps/server/src/orchestration/**, provider/Layers/*Adapter.ts and provider/Services/** are removed and replaced by apps/server/src/orchestration-v2/**, with the IPC surface renamed to ORCHESTRATION_V2_WS_METHODS. The files this PR touches either no longer exist or are rewritten, so it can't be rebased — it would need reimplementing against the V2 adapters.

This is not a judgement on the change itself. Several of these are real gaps we still want fixed; the base just moved out from under them.

Once #2829 merges, please rebase onto main, port the change to the V2 equivalent, and reopen (or open a fresh PR). Ping me and I'll prioritise the review.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Stuck on User Input Tool GUI

2 participants

@nateEc@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(server): resolve Claude user input prompts on stop - #4096

Closed
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-stale-user-input-gui
Closed

fix(server): resolve Claude user input prompts on stop#4096
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-stale-user-input-gui

Conversation

@nateEc

@nateEcnateEc commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Closes#4060.

Summary

  • Cancel pending Claude AskUserQuestion requests when the provider session stops.
  • Emit user-input.resolved during session stop so projected threads clear stale user-input prompts.
  • Keep SDK permission results as deny/cancel instead of allowing an empty answer payload.

Verification

  • corepack pnpm exec vp test run apps/server/src/provider/Layers/ClaudeAdapter.test.ts
  • corepack pnpm exec vp run typecheck
  • corepack pnpm exec vp check (passes with existing warnings outside this change)

Note

Medium Risk
Touches Claude SDK permission callbacks and session teardown ordering, but behavior is narrowly scoped to user-input lifecycle with broad new tests.

Overview
Fixes stale AskUserQuestion prompts by ensuring pending Claude user-input requests always get a single terminal outcome and the chat UI stops showing them once the provider session is gone.

Claude adapter adds settlePendingUserInput so each prompt is settled exactly once: it waits for user-input.requested before emitting user-input.resolved, handles races (abort vs stopSession vs provider exit), and returns deny with empty answers on cancel instead of allowing the tool. Session teardown (stopSession / stopAll) and abort listeners now route through this helper; duplicate respondToUserInput calls fail with ProviderAdapterRequestError; canUseTool denies when the session is missing or already stopped.

Web passes session status into derivePendingUserInputs so prompts are hidden when status is stopped, including legacy threads that never got a resolved event.

Reviewed by Cursor Bugbot for commit e8dc20d. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Resolve pending Claude AskUserQuestion prompts when a session stops

  • When a Claude session stops, all pending AskUserQuestion requests are now cancelled and emit a user-input.resolved event with empty answers and a deny result of 'User cancelled tool execution.'
  • A new settlePendingUserInput helper in ClaudeAdapter.ts ensures each request resolves exactly once, ordering the resolved event after the corresponding requested event.
  • canUseTool and handleAskUserQuestion now immediately deny with 'Claude session context is unavailable or stopped.' when called after session stop or with an already-aborted signal.
  • Duplicate respondToUserInput calls for the same request now return a ProviderAdapterRequestError instead of silently succeeding.
  • derivePendingUserInputs in session-logic.ts returns an empty list when session status is 'stopped', clearing stale prompts from the UI.

Macroscope summarized e8dc20d.

@coderabbitai

coderabbitaiBot commented Jul 17, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 0a9b1d75-6b94-42d7-965c-a2c8fab498f7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Jul 17, 2026
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts Outdated
@macroscopeapp

macroscopeappBot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces significant runtime behavior changes for handling pending user input prompts when Claude sessions stop, including new concurrency handling logic for race conditions. An unresolved review comment identifies inconsistent deny messages between abort and session-stop paths.

You can customize Macroscope's approvability policy. Learn more.

PR: pingdotgg#4096
Co-authored-by: codex <codex@users.noreply.github.com>
@juliusmarminge
juliusmarmingeforce-pushed the codex/fix-stale-user-input-gui branch from f7f07cf to 47aa733CompareJuly 20, 2026 17:11
@github-actionsgithub-actionsBot added size:L 100-499 changed lines (additions + deletions). and removed size:M 30-99 changed lines (additions + deletions). labels Jul 20, 2026
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts
- 在请求发布与注册之间建立不可中断的生命周期边界,停止后不再新增待处理输入。
- resolved 发布完成后再移除请求,并确保所有竞态等待者都会被释放。
- 增加停止后回调回归测试,并通过并发测试、vp check 与类型检查。

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit e8dc20d. Configure here.

return {
behavior: "deny",
message: "Claude session context is unavailable or stopped.",
} satisfies PermissionResult;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Abort deny uses stopped message

Medium Severity

Registration treats an already-aborted signal the same as a stopped session and returns deny with Claude session context is unavailable or stopped. That path never settles as cancelled, so the SDK sees a session-dead reason instead of the usual User cancelled tool execution. cancel deny when only the tool call was aborted.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit e8dc20d. Configure here.

@juliusmarminge

Copy link
Copy Markdown
Member

Closing in favor of #2829 (orchestration V2).

#2829 deletes the V1 orchestration layer this PR builds on — apps/server/src/orchestration/**, provider/Layers/*Adapter.ts and provider/Services/** are removed and replaced by apps/server/src/orchestration-v2/**, with the IPC surface renamed to ORCHESTRATION_V2_WS_METHODS. The files this PR touches either no longer exist or are rewritten, so it can't be rebased — it would need reimplementing against the V2 adapters.

This is not a judgement on the change itself. Several of these are real gaps we still want fixed; the base just moved out from under them.

Once #2829 merges, please rebase onto main, port the change to the V2 equivalent, and reopen (or open a fresh PR). Ping me and I'll prioritise the review.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Stuck on User Input Tool GUI

2 participants

@nateEc@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(server): resolve Claude user input prompts on stop - #4096

Closed
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-stale-user-input-gui
Closed

fix(server): resolve Claude user input prompts on stop#4096
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-stale-user-input-gui

Conversation

@nateEc

@nateEcnateEc commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Closes#4060.

Summary

  • Cancel pending Claude AskUserQuestion requests when the provider session stops.
  • Emit user-input.resolved during session stop so projected threads clear stale user-input prompts.
  • Keep SDK permission results as deny/cancel instead of allowing an empty answer payload.

Verification

  • corepack pnpm exec vp test run apps/server/src/provider/Layers/ClaudeAdapter.test.ts
  • corepack pnpm exec vp run typecheck
  • corepack pnpm exec vp check (passes with existing warnings outside this change)

Note

Medium Risk
Touches Claude SDK permission callbacks and session teardown ordering, but behavior is narrowly scoped to user-input lifecycle with broad new tests.

Overview
Fixes stale AskUserQuestion prompts by ensuring pending Claude user-input requests always get a single terminal outcome and the chat UI stops showing them once the provider session is gone.

Claude adapter adds settlePendingUserInput so each prompt is settled exactly once: it waits for user-input.requested before emitting user-input.resolved, handles races (abort vs stopSession vs provider exit), and returns deny with empty answers on cancel instead of allowing the tool. Session teardown (stopSession / stopAll) and abort listeners now route through this helper; duplicate respondToUserInput calls fail with ProviderAdapterRequestError; canUseTool denies when the session is missing or already stopped.

Web passes session status into derivePendingUserInputs so prompts are hidden when status is stopped, including legacy threads that never got a resolved event.

Reviewed by Cursor Bugbot for commit e8dc20d. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Resolve pending Claude AskUserQuestion prompts when a session stops

  • When a Claude session stops, all pending AskUserQuestion requests are now cancelled and emit a user-input.resolved event with empty answers and a deny result of 'User cancelled tool execution.'
  • A new settlePendingUserInput helper in ClaudeAdapter.ts ensures each request resolves exactly once, ordering the resolved event after the corresponding requested event.
  • canUseTool and handleAskUserQuestion now immediately deny with 'Claude session context is unavailable or stopped.' when called after session stop or with an already-aborted signal.
  • Duplicate respondToUserInput calls for the same request now return a ProviderAdapterRequestError instead of silently succeeding.
  • derivePendingUserInputs in session-logic.ts returns an empty list when session status is 'stopped', clearing stale prompts from the UI.

Macroscope summarized e8dc20d.

@coderabbitai

coderabbitaiBot commented Jul 17, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 0a9b1d75-6b94-42d7-965c-a2c8fab498f7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Jul 17, 2026
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts Outdated
@macroscopeapp

macroscopeappBot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces significant runtime behavior changes for handling pending user input prompts when Claude sessions stop, including new concurrency handling logic for race conditions. An unresolved review comment identifies inconsistent deny messages between abort and session-stop paths.

You can customize Macroscope's approvability policy. Learn more.

PR: pingdotgg#4096
Co-authored-by: codex <codex@users.noreply.github.com>
@juliusmarminge
juliusmarmingeforce-pushed the codex/fix-stale-user-input-gui branch from f7f07cf to 47aa733CompareJuly 20, 2026 17:11
@github-actionsgithub-actionsBot added size:L 100-499 changed lines (additions + deletions). and removed size:M 30-99 changed lines (additions + deletions). labels Jul 20, 2026
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts
- 在请求发布与注册之间建立不可中断的生命周期边界,停止后不再新增待处理输入。
- resolved 发布完成后再移除请求,并确保所有竞态等待者都会被释放。
- 增加停止后回调回归测试,并通过并发测试、vp check 与类型检查。

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit e8dc20d. Configure here.

return {
behavior: "deny",
message: "Claude session context is unavailable or stopped.",
} satisfies PermissionResult;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Abort deny uses stopped message

Medium Severity

Registration treats an already-aborted signal the same as a stopped session and returns deny with Claude session context is unavailable or stopped. That path never settles as cancelled, so the SDK sees a session-dead reason instead of the usual User cancelled tool execution. cancel deny when only the tool call was aborted.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit e8dc20d. Configure here.

@juliusmarminge

Copy link
Copy Markdown
Member

Closing in favor of #2829 (orchestration V2).

#2829 deletes the V1 orchestration layer this PR builds on — apps/server/src/orchestration/**, provider/Layers/*Adapter.ts and provider/Services/** are removed and replaced by apps/server/src/orchestration-v2/**, with the IPC surface renamed to ORCHESTRATION_V2_WS_METHODS. The files this PR touches either no longer exist or are rewritten, so it can't be rebased — it would need reimplementing against the V2 adapters.

This is not a judgement on the change itself. Several of these are real gaps we still want fixed; the base just moved out from under them.

Once #2829 merges, please rebase onto main, port the change to the V2 equivalent, and reopen (or open a fresh PR). Ping me and I'll prioritise the review.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Stuck on User Input Tool GUI

2 participants

@nateEc@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix(server): resolve Claude user input prompts on stop - #4096

Closed
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-stale-user-input-gui
Closed

fix(server): resolve Claude user input prompts on stop#4096
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-stale-user-input-gui

Conversation

@nateEc

@nateEcnateEc commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Closes#4060.

Summary

  • Cancel pending Claude AskUserQuestion requests when the provider session stops.
  • Emit user-input.resolved during session stop so projected threads clear stale user-input prompts.
  • Keep SDK permission results as deny/cancel instead of allowing an empty answer payload.

Verification

  • corepack pnpm exec vp test run apps/server/src/provider/Layers/ClaudeAdapter.test.ts
  • corepack pnpm exec vp run typecheck
  • corepack pnpm exec vp check (passes with existing warnings outside this change)

Note

Medium Risk
Touches Claude SDK permission callbacks and session teardown ordering, but behavior is narrowly scoped to user-input lifecycle with broad new tests.

Overview
Fixes stale AskUserQuestion prompts by ensuring pending Claude user-input requests always get a single terminal outcome and the chat UI stops showing them once the provider session is gone.

Claude adapter adds settlePendingUserInput so each prompt is settled exactly once: it waits for user-input.requested before emitting user-input.resolved, handles races (abort vs stopSession vs provider exit), and returns deny with empty answers on cancel instead of allowing the tool. Session teardown (stopSession / stopAll) and abort listeners now route through this helper; duplicate respondToUserInput calls fail with ProviderAdapterRequestError; canUseTool denies when the session is missing or already stopped.

Web passes session status into derivePendingUserInputs so prompts are hidden when status is stopped, including legacy threads that never got a resolved event.

Reviewed by Cursor Bugbot for commit e8dc20d. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Resolve pending Claude AskUserQuestion prompts when a session stops

  • When a Claude session stops, all pending AskUserQuestion requests are now cancelled and emit a user-input.resolved event with empty answers and a deny result of 'User cancelled tool execution.'
  • A new settlePendingUserInput helper in ClaudeAdapter.ts ensures each request resolves exactly once, ordering the resolved event after the corresponding requested event.
  • canUseTool and handleAskUserQuestion now immediately deny with 'Claude session context is unavailable or stopped.' when called after session stop or with an already-aborted signal.
  • Duplicate respondToUserInput calls for the same request now return a ProviderAdapterRequestError instead of silently succeeding.
  • derivePendingUserInputs in session-logic.ts returns an empty list when session status is 'stopped', clearing stale prompts from the UI.

Macroscope summarized e8dc20d.

@coderabbitai

coderabbitaiBot commented Jul 17, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 0a9b1d75-6b94-42d7-965c-a2c8fab498f7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Jul 17, 2026
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts Outdated
@macroscopeapp

macroscopeappBot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces significant runtime behavior changes for handling pending user input prompts when Claude sessions stop, including new concurrency handling logic for race conditions. An unresolved review comment identifies inconsistent deny messages between abort and session-stop paths.

You can customize Macroscope's approvability policy. Learn more.

PR: pingdotgg#4096
Co-authored-by: codex <codex@users.noreply.github.com>
@juliusmarminge
juliusmarmingeforce-pushed the codex/fix-stale-user-input-gui branch from f7f07cf to 47aa733CompareJuly 20, 2026 17:11
@github-actionsgithub-actionsBot added size:L 100-499 changed lines (additions + deletions). and removed size:M 30-99 changed lines (additions + deletions). labels Jul 20, 2026
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts
- 在请求发布与注册之间建立不可中断的生命周期边界,停止后不再新增待处理输入。
- resolved 发布完成后再移除请求,并确保所有竞态等待者都会被释放。
- 增加停止后回调回归测试,并通过并发测试、vp check 与类型检查。

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit e8dc20d. Configure here.

return {
behavior: "deny",
message: "Claude session context is unavailable or stopped.",
} satisfies PermissionResult;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Abort deny uses stopped message

Medium Severity

Registration treats an already-aborted signal the same as a stopped session and returns deny with Claude session context is unavailable or stopped. That path never settles as cancelled, so the SDK sees a session-dead reason instead of the usual User cancelled tool execution. cancel deny when only the tool call was aborted.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit e8dc20d. Configure here.

@juliusmarminge

Copy link
Copy Markdown
Member

Closing in favor of #2829 (orchestration V2).

#2829 deletes the V1 orchestration layer this PR builds on — apps/server/src/orchestration/**, provider/Layers/*Adapter.ts and provider/Services/** are removed and replaced by apps/server/src/orchestration-v2/**, with the IPC surface renamed to ORCHESTRATION_V2_WS_METHODS. The files this PR touches either no longer exist or are rewritten, so it can't be rebased — it would need reimplementing against the V2 adapters.

This is not a judgement on the change itself. Several of these are real gaps we still want fixed; the base just moved out from under them.

Once #2829 merges, please rebase onto main, port the change to the V2 equivalent, and reopen (or open a fresh PR). Ping me and I'll prioritise the review.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Stuck on User Input Tool GUI

2 participants

@nateEc@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(server): resolve Claude user input prompts on stop - #4096

Closed
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-stale-user-input-gui
Closed

fix(server): resolve Claude user input prompts on stop#4096
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-stale-user-input-gui

Conversation

@nateEc

@nateEcnateEc commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Closes#4060.

Summary

  • Cancel pending Claude AskUserQuestion requests when the provider session stops.
  • Emit user-input.resolved during session stop so projected threads clear stale user-input prompts.
  • Keep SDK permission results as deny/cancel instead of allowing an empty answer payload.

Verification

  • corepack pnpm exec vp test run apps/server/src/provider/Layers/ClaudeAdapter.test.ts
  • corepack pnpm exec vp run typecheck
  • corepack pnpm exec vp check (passes with existing warnings outside this change)

Note

Medium Risk
Touches Claude SDK permission callbacks and session teardown ordering, but behavior is narrowly scoped to user-input lifecycle with broad new tests.

Overview
Fixes stale AskUserQuestion prompts by ensuring pending Claude user-input requests always get a single terminal outcome and the chat UI stops showing them once the provider session is gone.

Claude adapter adds settlePendingUserInput so each prompt is settled exactly once: it waits for user-input.requested before emitting user-input.resolved, handles races (abort vs stopSession vs provider exit), and returns deny with empty answers on cancel instead of allowing the tool. Session teardown (stopSession / stopAll) and abort listeners now route through this helper; duplicate respondToUserInput calls fail with ProviderAdapterRequestError; canUseTool denies when the session is missing or already stopped.

Web passes session status into derivePendingUserInputs so prompts are hidden when status is stopped, including legacy threads that never got a resolved event.

Reviewed by Cursor Bugbot for commit e8dc20d. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Resolve pending Claude AskUserQuestion prompts when a session stops

  • When a Claude session stops, all pending AskUserQuestion requests are now cancelled and emit a user-input.resolved event with empty answers and a deny result of 'User cancelled tool execution.'
  • A new settlePendingUserInput helper in ClaudeAdapter.ts ensures each request resolves exactly once, ordering the resolved event after the corresponding requested event.
  • canUseTool and handleAskUserQuestion now immediately deny with 'Claude session context is unavailable or stopped.' when called after session stop or with an already-aborted signal.
  • Duplicate respondToUserInput calls for the same request now return a ProviderAdapterRequestError instead of silently succeeding.
  • derivePendingUserInputs in session-logic.ts returns an empty list when session status is 'stopped', clearing stale prompts from the UI.

Macroscope summarized e8dc20d.

@coderabbitai

coderabbitaiBot commented Jul 17, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 0a9b1d75-6b94-42d7-965c-a2c8fab498f7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Jul 17, 2026
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts Outdated
@macroscopeapp

macroscopeappBot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces significant runtime behavior changes for handling pending user input prompts when Claude sessions stop, including new concurrency handling logic for race conditions. An unresolved review comment identifies inconsistent deny messages between abort and session-stop paths.

You can customize Macroscope's approvability policy. Learn more.

PR: pingdotgg#4096
Co-authored-by: codex <codex@users.noreply.github.com>
@juliusmarminge
juliusmarmingeforce-pushed the codex/fix-stale-user-input-gui branch from f7f07cf to 47aa733CompareJuly 20, 2026 17:11
@github-actionsgithub-actionsBot added size:L 100-499 changed lines (additions + deletions). and removed size:M 30-99 changed lines (additions + deletions). labels Jul 20, 2026
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts
- 在请求发布与注册之间建立不可中断的生命周期边界,停止后不再新增待处理输入。
- resolved 发布完成后再移除请求,并确保所有竞态等待者都会被释放。
- 增加停止后回调回归测试,并通过并发测试、vp check 与类型检查。

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit e8dc20d. Configure here.

return {
behavior: "deny",
message: "Claude session context is unavailable or stopped.",
} satisfies PermissionResult;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Abort deny uses stopped message

Medium Severity

Registration treats an already-aborted signal the same as a stopped session and returns deny with Claude session context is unavailable or stopped. That path never settles as cancelled, so the SDK sees a session-dead reason instead of the usual User cancelled tool execution. cancel deny when only the tool call was aborted.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit e8dc20d. Configure here.

@juliusmarminge

Copy link
Copy Markdown
Member

Closing in favor of #2829 (orchestration V2).

#2829 deletes the V1 orchestration layer this PR builds on — apps/server/src/orchestration/**, provider/Layers/*Adapter.ts and provider/Services/** are removed and replaced by apps/server/src/orchestration-v2/**, with the IPC surface renamed to ORCHESTRATION_V2_WS_METHODS. The files this PR touches either no longer exist or are rewritten, so it can't be rebased — it would need reimplementing against the V2 adapters.

This is not a judgement on the change itself. Several of these are real gaps we still want fixed; the base just moved out from under them.

Once #2829 merges, please rebase onto main, port the change to the V2 equivalent, and reopen (or open a fresh PR). Ping me and I'll prioritise the review.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Stuck on User Input Tool GUI

2 participants

@nateEc@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(server): resolve Claude user input prompts on stop - #4096

Closed
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-stale-user-input-gui
Closed

fix(server): resolve Claude user input prompts on stop#4096
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-stale-user-input-gui

Conversation

@nateEc

@nateEcnateEc commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Closes#4060.

Summary

  • Cancel pending Claude AskUserQuestion requests when the provider session stops.
  • Emit user-input.resolved during session stop so projected threads clear stale user-input prompts.
  • Keep SDK permission results as deny/cancel instead of allowing an empty answer payload.

Verification

  • corepack pnpm exec vp test run apps/server/src/provider/Layers/ClaudeAdapter.test.ts
  • corepack pnpm exec vp run typecheck
  • corepack pnpm exec vp check (passes with existing warnings outside this change)

Note

Medium Risk
Touches Claude SDK permission callbacks and session teardown ordering, but behavior is narrowly scoped to user-input lifecycle with broad new tests.

Overview
Fixes stale AskUserQuestion prompts by ensuring pending Claude user-input requests always get a single terminal outcome and the chat UI stops showing them once the provider session is gone.

Claude adapter adds settlePendingUserInput so each prompt is settled exactly once: it waits for user-input.requested before emitting user-input.resolved, handles races (abort vs stopSession vs provider exit), and returns deny with empty answers on cancel instead of allowing the tool. Session teardown (stopSession / stopAll) and abort listeners now route through this helper; duplicate respondToUserInput calls fail with ProviderAdapterRequestError; canUseTool denies when the session is missing or already stopped.

Web passes session status into derivePendingUserInputs so prompts are hidden when status is stopped, including legacy threads that never got a resolved event.

Reviewed by Cursor Bugbot for commit e8dc20d. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Resolve pending Claude AskUserQuestion prompts when a session stops

  • When a Claude session stops, all pending AskUserQuestion requests are now cancelled and emit a user-input.resolved event with empty answers and a deny result of 'User cancelled tool execution.'
  • A new settlePendingUserInput helper in ClaudeAdapter.ts ensures each request resolves exactly once, ordering the resolved event after the corresponding requested event.
  • canUseTool and handleAskUserQuestion now immediately deny with 'Claude session context is unavailable or stopped.' when called after session stop or with an already-aborted signal.
  • Duplicate respondToUserInput calls for the same request now return a ProviderAdapterRequestError instead of silently succeeding.
  • derivePendingUserInputs in session-logic.ts returns an empty list when session status is 'stopped', clearing stale prompts from the UI.

Macroscope summarized e8dc20d.

@coderabbitai

coderabbitaiBot commented Jul 17, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 0a9b1d75-6b94-42d7-965c-a2c8fab498f7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Jul 17, 2026
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts Outdated
@macroscopeapp

macroscopeappBot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces significant runtime behavior changes for handling pending user input prompts when Claude sessions stop, including new concurrency handling logic for race conditions. An unresolved review comment identifies inconsistent deny messages between abort and session-stop paths.

You can customize Macroscope's approvability policy. Learn more.

PR: pingdotgg#4096
Co-authored-by: codex <codex@users.noreply.github.com>
@juliusmarminge
juliusmarmingeforce-pushed the codex/fix-stale-user-input-gui branch from f7f07cf to 47aa733CompareJuly 20, 2026 17:11
@github-actionsgithub-actionsBot added size:L 100-499 changed lines (additions + deletions). and removed size:M 30-99 changed lines (additions + deletions). labels Jul 20, 2026
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts
- 在请求发布与注册之间建立不可中断的生命周期边界,停止后不再新增待处理输入。
- resolved 发布完成后再移除请求,并确保所有竞态等待者都会被释放。
- 增加停止后回调回归测试,并通过并发测试、vp check 与类型检查。

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit e8dc20d. Configure here.

return {
behavior: "deny",
message: "Claude session context is unavailable or stopped.",
} satisfies PermissionResult;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Abort deny uses stopped message

Medium Severity

Registration treats an already-aborted signal the same as a stopped session and returns deny with Claude session context is unavailable or stopped. That path never settles as cancelled, so the SDK sees a session-dead reason instead of the usual User cancelled tool execution. cancel deny when only the tool call was aborted.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit e8dc20d. Configure here.

@juliusmarminge

Copy link
Copy Markdown
Member

Closing in favor of #2829 (orchestration V2).

#2829 deletes the V1 orchestration layer this PR builds on — apps/server/src/orchestration/**, provider/Layers/*Adapter.ts and provider/Services/** are removed and replaced by apps/server/src/orchestration-v2/**, with the IPC surface renamed to ORCHESTRATION_V2_WS_METHODS. The files this PR touches either no longer exist or are rewritten, so it can't be rebased — it would need reimplementing against the V2 adapters.

This is not a judgement on the change itself. Several of these are real gaps we still want fixed; the base just moved out from under them.

Once #2829 merges, please rebase onto main, port the change to the V2 equivalent, and reopen (or open a fresh PR). Ping me and I'll prioritise the review.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Stuck on User Input Tool GUI

2 participants

@nateEc@juliusmarminge
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix(server): resolve Claude user input prompts on stop - #4096

Closed
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-stale-user-input-gui
Closed

fix(server): resolve Claude user input prompts on stop#4096
nateEc wants to merge 2 commits into
pingdotgg:mainfrom
nateEc:codex/fix-stale-user-input-gui

Conversation

@nateEc

@nateEcnateEc commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Closes#4060.

Summary

  • Cancel pending Claude AskUserQuestion requests when the provider session stops.
  • Emit user-input.resolved during session stop so projected threads clear stale user-input prompts.
  • Keep SDK permission results as deny/cancel instead of allowing an empty answer payload.

Verification

  • corepack pnpm exec vp test run apps/server/src/provider/Layers/ClaudeAdapter.test.ts
  • corepack pnpm exec vp run typecheck
  • corepack pnpm exec vp check (passes with existing warnings outside this change)

Note

Medium Risk
Touches Claude SDK permission callbacks and session teardown ordering, but behavior is narrowly scoped to user-input lifecycle with broad new tests.

Overview
Fixes stale AskUserQuestion prompts by ensuring pending Claude user-input requests always get a single terminal outcome and the chat UI stops showing them once the provider session is gone.

Claude adapter adds settlePendingUserInput so each prompt is settled exactly once: it waits for user-input.requested before emitting user-input.resolved, handles races (abort vs stopSession vs provider exit), and returns deny with empty answers on cancel instead of allowing the tool. Session teardown (stopSession / stopAll) and abort listeners now route through this helper; duplicate respondToUserInput calls fail with ProviderAdapterRequestError; canUseTool denies when the session is missing or already stopped.

Web passes session status into derivePendingUserInputs so prompts are hidden when status is stopped, including legacy threads that never got a resolved event.

Reviewed by Cursor Bugbot for commit e8dc20d. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Resolve pending Claude AskUserQuestion prompts when a session stops

  • When a Claude session stops, all pending AskUserQuestion requests are now cancelled and emit a user-input.resolved event with empty answers and a deny result of 'User cancelled tool execution.'
  • A new settlePendingUserInput helper in ClaudeAdapter.ts ensures each request resolves exactly once, ordering the resolved event after the corresponding requested event.
  • canUseTool and handleAskUserQuestion now immediately deny with 'Claude session context is unavailable or stopped.' when called after session stop or with an already-aborted signal.
  • Duplicate respondToUserInput calls for the same request now return a ProviderAdapterRequestError instead of silently succeeding.
  • derivePendingUserInputs in session-logic.ts returns an empty list when session status is 'stopped', clearing stale prompts from the UI.

Macroscope summarized e8dc20d.

@coderabbitai

coderabbitaiBot commented Jul 17, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 0a9b1d75-6b94-42d7-965c-a2c8fab498f7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Jul 17, 2026
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts Outdated
@macroscopeapp

macroscopeappBot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces significant runtime behavior changes for handling pending user input prompts when Claude sessions stop, including new concurrency handling logic for race conditions. An unresolved review comment identifies inconsistent deny messages between abort and session-stop paths.

You can customize Macroscope's approvability policy. Learn more.

PR: pingdotgg#4096
Co-authored-by: codex <codex@users.noreply.github.com>
@juliusmarminge
juliusmarmingeforce-pushed the codex/fix-stale-user-input-gui branch from f7f07cf to 47aa733CompareJuly 20, 2026 17:11
@github-actionsgithub-actionsBot added size:L 100-499 changed lines (additions + deletions). and removed size:M 30-99 changed lines (additions + deletions). labels Jul 20, 2026
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts
Comment threadapps/server/src/provider/Layers/ClaudeAdapter.ts
- 在请求发布与注册之间建立不可中断的生命周期边界,停止后不再新增待处理输入。
- resolved 发布完成后再移除请求,并确保所有竞态等待者都会被释放。
- 增加停止后回调回归测试,并通过并发测试、vp check 与类型检查。

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit e8dc20d. Configure here.

return {
behavior: "deny",
message: "Claude session context is unavailable or stopped.",
} satisfies PermissionResult;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Abort deny uses stopped message

Medium Severity

Registration treats an already-aborted signal the same as a stopped session and returns deny with Claude session context is unavailable or stopped. That path never settles as cancelled, so the SDK sees a session-dead reason instead of the usual User cancelled tool execution. cancel deny when only the tool call was aborted.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit e8dc20d. Configure here.

@juliusmarminge

Copy link
Copy Markdown
Member

Closing in favor of #2829 (orchestration V2).

#2829 deletes the V1 orchestration layer this PR builds on — apps/server/src/orchestration/**, provider/Layers/*Adapter.ts and provider/Services/** are removed and replaced by apps/server/src/orchestration-v2/**, with the IPC surface renamed to ORCHESTRATION_V2_WS_METHODS. The files this PR touches either no longer exist or are rewritten, so it can't be rebased — it would need reimplementing against the V2 adapters.

This is not a judgement on the change itself. Several of these are real gaps we still want fixed; the base just moved out from under them.

Once #2829 merges, please rebase onto main, port the change to the V2 equivalent, and reopen (or open a fresh PR). Ping me and I'll prioritise the review.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Stuck on User Input Tool GUI

2 participants

@nateEc@juliusmarminge