Skip to content

fix(cursor): explain empty exec results + forbid native probing in code mode - #2662

Closed
lidge-jun wants to merge 1 commit into
codex/cursor-gap-6from
codex/cursor-gap-7
Closed

fix(cursor): explain empty exec results + forbid native probing in code mode#2662
lidge-jun wants to merge 1 commit into
codex/cursor-gap-6from
codex/cursor-gap-7

Conversation

@lidge-jun

Copy link
Copy Markdown
Owner

Summary

  • Live cursor-route subagents repeatedly misread empty exec results as lost context or a blocked tool ("이전 exec 결과가 비어 있어서", "로컬 셸이 막혀서"), spiraling into re-orientation retries and evidence-hook loops. Root cause: a code-mode exec cell that never calls text(...)/notify(...) legitimately returns empty output, and normalizeCursorToolResultText only rewrote empties for Computer-Use/node_repl tool names — the Codex exec/shell bridge got a blank [tool_result]. Now bridge-tool empties (flat + mcp_opencodex-responses_* display aliases) are rewritten into an explanatory non-error message telling the model the result is not lost and how to surface values.
  • The NEVER-probe-native guidance shipped in gap-6 only rode the bare-exec branch; code-mode sessions kept probing Cursor-native Shell/Read and narrating surface-switching. The same prohibition now rides the code-mode note.

Stacked on #2656 (codex/cursor-gap-6).

Verification

  • bun test tests/cursor-exec-empty-result.test.ts — 6 pass (bridge empties across all alias shapes, non-empty passthrough, computer-use semantics preserved, unrelated tools untouched).
  • bun test tests/cursor-tool-definitions.test.ts tests/cursor-blob.test.ts tests/cursor-request-builder.test.ts — 156 pass 0 fail.
  • bun x tsc --noEmit — clean.

Checklist

  • Focused tests green
  • Typecheck clean
  • Empty-exec rewrite is non-error (no false failure states)
  • Devlog trail in 260826_cursor_responses_gap

@lidge-jun
lidge-jun requested a review from Ingwannu as a code owner August 26, 2026 04:06
@coderabbitai

coderabbitai Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (2)
  • ^dev$
  • ^preview$

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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3d1f4580-1306-4c3b-8667-128a949cf994

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

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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 65e8fe0e8a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if (isCodexExecBridgeTool(options.toolName, options.toolNamespace) && EMPTY_EXEC_OUTPUT_REGEX.test(text.trim())) {
return {
text: "[empty output: the exec cell completed but emitted nothing. This is NOT lost context and NOT a blocked tool — in code mode call text(...) or notify(...) on any value you need to see (a bare await tools.exec_command(...) is not echoed automatically); in shell mode the command simply printed nothing. Do not re-run the same call expecting different output.]",
isError: false,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve existing errors when annotating empty exec results

When an exec or shell-bridge result arrives with isError: true and an empty payload—or even the explicitly matched Script failed wrapper—this branch overwrites the flag with false. The Cursor wire result therefore reports a failed command as successful and tells the model not to retry, potentially allowing work to continue from a command that never completed; preserve the incoming isError value or apply the non-error annotation only when it is already false.

AGENTS.md reference: src/AGENTS.md:L19-L19

Useful? React with 👍 / 👎.

* re-orientation retries (devlog 260826_cursor_responses_gap, live subagent transcripts).
*/
function isCodexExecBridgeTool(toolName?: string, toolNamespace?: string): boolean {
if (toolNamespace && toolNamespace.includes("opencodex-responses")) return true;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Match only exec aliases under the Responses namespace

When any unrelated Responses-owned tool returns empty output, this namespace check classifies it as an exec bridge before inspecting its name. For example, wait with namespace opencodex-responses is recognized by isCursorWaitTool, while display aliases such as mcp_opencodex-responses_apply_patch share the same generic prefix; both now receive misleading exec-cell guidance rather than retaining their actual result semantics. Require the normalized tool name to be exactly exec, exec_command, or shell_command instead of accepting the provider namespace or every prefixed tool.

AGENTS.md reference: src/AGENTS.md:L19-L19

Useful? React with 👍 / 👎.

@github-actions github-actions Bot added the bug Something isn't working label Aug 26, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@lidge-jun

Copy link
Copy Markdown
Owner Author

리뷰 · 우선순위 56 / 80

설명

이 풀 리퀘스트는 코드 모드 exec가 text(...)나 notify(...)를 부르지 않아 결과가 비어 있을 때, 모델이 이전 결과가 사라졌거나 도구가 막혔다고 착각하지 않게 설명을 넣습니다. 지금 dev의 src/adapters/cursor/tool-result-normalize.ts 70-91줄 normalizeCursorToolResultText는 Computer Use와 node_repl 이름에만 빈 출력을 고칩니다. 52-53줄 EMPTY_EXEC_OUTPUT_REGEX는 진짜 빈 문자열뿐 아니라 Script completed와 Output: 래퍼도 빈 출력으로 봅니다. Codex exec/shell 브리지는 그 정규식을 타도 설명이 없어서, 빈 [tool_result]가 그대로 모델에 갑니다.

고침은 isCodexExecBridgeTool을 더합니다. exec, exec_command, shell_command, mcp_opencodex-responses_ 접두사, 네임스페이스에 opencodex-responses가 있으면 같은 길로 갑니다. 빈 출력이면 isError는 false로 두고, 사라진 맥락이 아니며 text(...)를 쓰라는 글을 넣습니다. Computer Use 빈 출력은 여전히 isError true입니다. 테스트가 그 차이를 고정합니다. 비어 있지 않은 exec 출력은 바이트 그대로 통과합니다.

두 번째 변경은 안내문입니다. src/adapters/cursor/tool-definitions.ts 656-658줄 코드 모드 안내에, 네이티브 Shell/Read를 탐색하지 말라는 문장을 붙입니다. 지금 665-667줄의 Prefer the Codex shell bridge 문장은 hasBareExec일 때만 타고, 코드 모드만 있는 턴은 그 금지를 못 봅니다. 코드 모드 쪽에 같은 금지를 옮기는 것은 맞습니다. 다만 문장이 길어지고, NEVER와 FIRST attempt가 모델마다 다르게 읽힐 수 있습니다.

이 PR은 베이스가 #2656입니다. 현재 dev(7181ebd) 위에 혼자 합칠 수 없습니다. 네임스페이스 검사는 includes("opencodex-responses")라서, 비슷한 글자가 들어간 다른 네임스페이스도 빈 출력을 설명 글로 바꿀 수 있습니다. 또한 빈 출력을 설명으로 바꾸면, 정말로 실패한 침묵 오류를 성공처럼 읽게 할 수 있습니다. isError false가 그 지점입니다.

src/adapters/cursor/tool-result-normalize.ts:76 - 빈 출력 다시 쓰기가 Computer Use 이름에만 걸려 Codex exec가 빈 [tool_result]를 남깁니다.
src/adapters/cursor/tool-definitions.ts:656 - 코드 모드 안내에 네이티브 탐색 금지가 없어 hasBareExec가 아닌 턴은 금지 문장을 못 봅니다.
경로/심볼 - toolNamespace.includes("opencodex-responses")는 비슷한 이름도 브리지로 볼 수 있습니다.
경로/심볼 - 베이스가 #2656이라 현재 dev에는 혼자 합칠 수 없습니다.
경로/심볼 - 빈 exec를 오류가 아니라고 표시하면, 진짜 침묵 실패와 구분이 안 됩니다.

메인테이너의 판단이 필요한 지점

  • 빈 exec를 설명만 할 성공으로 둘지, 약한 경고로 둘지 정해야 합니다.
  • 브리지 이름 목록을 정확한 집합으로 둘지, 접두사/includes로 넓힐지 정해야 합니다.
  • #2656이 먼저 들어간 뒤에만 볼지 정해야 합니다.

너의 추천

#2650-#2656 스택이 먼저 들어간 뒤에 이 PR을 합치세요. 지금 dev에 직접 합치지 마세요. 합치기 전에는 네임스페이스 검사를 더 좁히고, 빈 출력이 진짜 실패일 때의 메시지를 한 줄로 구분해 두세요. 미리보기 배포는 계획에 없습니다.

이 댓글은 grok-bot이 작성했습니다

@lidge-jun
lidge-jun deleted the branch codex/cursor-gap-6 August 26, 2026 06:08
@lidge-jun lidge-jun closed this Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant