Skip to content

Fix shell abort classification for Bash and PowerShell - #1688

Merged
kevincodex1 merged 4 commits into
Twigpine:mainfrom
chioarub:pr/tool-bash-abort-semantics
Jul 2, 2026
Merged

kevincodex1 merged 4 commits into
Twigpine:mainfrom
chioarub:pr/tool-bash-abort-semantics

Conversation

@chioarub

@chioarub chioarub commented Jun 17, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • normalize shell abort reasons and attach safe abort metadata to shell command results
  • classify QueryGuard, user, interrupt, background, and parent-ended abort kills as cancellations instead of ordinary shell failures
  • keep command nonzero exits and shell tool timeouts as failures, preserving existing background command behavior
  • surface specific model-facing cancellation messages for Bash and PowerShell without logging raw commands or command output

Root Cause

Shell tools only suppressed ShellError for the narrow interrupt path. QueryGuard and user-cancel flows can arrive with other abort reasons, so abort-driven process kills could be reported as generic shell failures rather than cancellations.

Validation

  • bun test src/utils/abortReasons.test.ts src/utils/ShellCommand.test.ts src/tools/BashTool/BashTool.errorOutput.test.ts src/utils/toolErrors.test.ts
  • bun run typecheck
  • git diff --check

Summary by CodeRabbit

  • New Features

    • Shell command error messages now include specific abort reasons when commands are cancelled or timed out
    • Enhanced handling to distinguish between user-initiated cancellations and automatic timeouts
  • Bug Fixes

    • Improved command cancellation tracking and error reporting to properly surface cancellation context

@chioarub
chioarub marked this pull request as ready for review June 17, 2026 08:46
@coderabbitai

coderabbitai Bot commented Jun 17, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Introduces a new AbortReason string-union type with normalization, classification, and message helpers. Threads abort metadata (isAbort, abortReason, abortMessage, signalAborted, signal, durationMs) through ExecResult, ShellCommandImpl, Shell.ts, ShellError, and toolErrors. Both BashTool and PowerShellTool output schemas and analytics are updated to surface these fields.

Changes

Abort Reason Infrastructure and Tool Integration

Layer / File(s) Summary
AbortReason type, normalization, and message helpers
src/utils/abortReasons.ts, src/utils/abortReasons.test.ts
Defines the AbortReason union, alias map (user-cancel → user-abort), normalizeAbortReason, isQueryLevelAbort, and getShellAbortMessage; test suite validates all mappings and message completeness.
ExecResult and ShellCommandImpl abort tracking
src/utils/ShellCommand.ts, src/utils/ShellCommand.test.ts
Extends ExecResult with signal, durationMs, signalAborted, isAbort, abortReason, abortMessage, stdoutLength, stderrLength; ShellCommandImpl tracks #killedByAbort, #timedOut, #exitSignal, #startTime; AbortedShellCommand/createAbortedCommand accept abortReason; createFailedCommand gains optional code param; tests cover abort vs. timeout distinctions.
Shell.ts abort normalization at spawn boundaries
src/utils/Shell.ts
Applies normalizeAbortReason to pre-spawn aborts and the exec catch-block abort branch, passing normalized reason into createAbortedCommand.
ShellError abort metadata and toolErrors rendering
src/utils/errors.ts, src/utils/toolErrors.ts, src/utils/toolErrors.test.ts
ShellError gains abortReason, abortMessage, isAbort fields with derivation logic; formatError uses isAbortError; getErrorParts uses abortMessage fallback; tests cover override and derivation rules.
BashTool abort output and analytics
src/tools/BashTool/BashTool.tsx, src/tools/BashTool/BashTool.errorOutput.test.ts
Output schema and Out type gain abort fields; call() switches to result.isAbort; ShellError throw passes abort metadata; interrupted error rendering uses abortMessage; analytics extended; regression tests cover query-timeout and user-cancel paths.
PowerShellTool abort output and analytics
src/tools/PowerShellTool/PowerShellTool.tsx
Mirrors BashTool: output schema, call() abort detection, ShellError throw, error rendering, backgrounded-path isAbort: false, analytics, and Out payload all updated to match abort contract.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested reviewers

  • kevincodex1
  • jatmn
🚥 Pre-merge checks | ✅ 6 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (6 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main focus of the PR: fixing shell abort classification for both Bash and PowerShell tools.
Description check ✅ Passed The description covers the required sections with clear explanations of what changed, why, and includes specific validation steps, though it deviates from the template structure.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Risk Surface Disclosed ✅ Passed PR touches background execution through abort classification changes only (no mechanism changes). The single review comment addresses TypeScript exhaustiveness (non-blocking). No risk surface call-...
No Hidden Policy Change ✅ Passed PR explicitly documents abort classification and telemetry changes: aborts classified as cancellations with safe enum abort_reason values, no hidden trust-model, routing, permission, or network pol...

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

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

Warning

Review ran into problems

🔥 Problems

Stopped waiting for pipeline failures after 30000ms. One of your pipelines takes longer than our 30000ms fetch window to run, so review may not consider pipeline-failure results for inline comments if any failures occurred after the fetch window. Increase the timeout if you want to wait longer or run a @coderabbit review after the pipeline has finished.


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

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/utils/abortReasons.ts`:
- Around line 48-64: To improve exhaustiveness checking for future
maintainability, refactor the switch statement in getShellAbortMessage to
explicitly list each case separately instead of using fall-through cases. Expand
the grouped cases for user-abort, interrupt, parent-ended, and unknown-abort to
each have their own case statement with the same return message, which will
enable TypeScript to warn if a new AbortReason is added to the type but not
handled in the switch statement.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: cae57a5b-66dd-41a9-9f97-1bbf1f4b0696

📥 Commits

Reviewing files that changed from the base of the PR and between 2351811 and ed1dedd.

📒 Files selected for processing (11)
  • src/tools/BashTool/BashTool.errorOutput.test.ts
  • src/tools/BashTool/BashTool.tsx
  • src/tools/PowerShellTool/PowerShellTool.tsx
  • src/utils/Shell.ts
  • src/utils/ShellCommand.test.ts
  • src/utils/ShellCommand.ts
  • src/utils/abortReasons.test.ts
  • src/utils/abortReasons.ts
  • src/utils/errors.ts
  • src/utils/toolErrors.test.ts
  • src/utils/toolErrors.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (11)
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript with strict mode and ESM imports

Files:

  • src/utils/ShellCommand.test.ts
  • src/utils/toolErrors.test.ts
  • src/utils/abortReasons.ts
  • src/utils/abortReasons.test.ts
  • src/utils/toolErrors.ts
  • src/tools/BashTool/BashTool.tsx
  • src/tools/BashTool/BashTool.errorOutput.test.ts
  • src/utils/Shell.ts
  • src/tools/PowerShellTool/PowerShellTool.tsx
  • src/utils/ShellCommand.ts
  • src/utils/errors.ts
{src/services/**/*.ts,src/utils/**/*.ts}

📄 CodeRabbit inference engine (AGENTS.md)

Use execa for child processes

Files:

  • src/utils/ShellCommand.test.ts
  • src/utils/toolErrors.test.ts
  • src/utils/abortReasons.ts
  • src/utils/abortReasons.test.ts
  • src/utils/toolErrors.ts
  • src/utils/Shell.ts
  • src/utils/ShellCommand.ts
  • src/utils/errors.ts
**/*.{ts,tsx,js,jsx,py,json,md}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Follow the existing code style in the touched files

Files:

  • src/utils/ShellCommand.test.ts
  • src/utils/toolErrors.test.ts
  • src/utils/abortReasons.ts
  • src/utils/abortReasons.test.ts
  • src/utils/toolErrors.ts
  • src/tools/BashTool/BashTool.tsx
  • src/tools/BashTool/BashTool.errorOutput.test.ts
  • src/utils/Shell.ts
  • src/tools/PowerShellTool/PowerShellTool.tsx
  • src/utils/ShellCommand.ts
  • src/utils/errors.ts
**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add or update tests when the change affects behavior

Files:

  • src/utils/ShellCommand.test.ts
  • src/utils/toolErrors.test.ts
  • src/utils/abortReasons.test.ts
  • src/tools/BashTool/BashTool.errorOutput.test.ts
**/*.test.{ts,tsx,js}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Test the exact provider/model path you changed when possible

Files:

  • src/utils/ShellCommand.test.ts
  • src/utils/toolErrors.test.ts
  • src/utils/abortReasons.test.ts
  • src/tools/BashTool/BashTool.errorOutput.test.ts
**/*.{ts,tsx,js,jsx,py}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Keep comments useful and concise

Files:

  • src/utils/ShellCommand.test.ts
  • src/utils/toolErrors.test.ts
  • src/utils/abortReasons.ts
  • src/utils/abortReasons.test.ts
  • src/utils/toolErrors.ts
  • src/tools/BashTool/BashTool.tsx
  • src/tools/BashTool/BashTool.errorOutput.test.ts
  • src/utils/Shell.ts
  • src/tools/PowerShellTool/PowerShellTool.tsx
  • src/utils/ShellCommand.ts
  • src/utils/errors.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Follow TypeScript strict mode and type safety practices by running typecheck before submitting

Files:

  • src/utils/ShellCommand.test.ts
  • src/utils/toolErrors.test.ts
  • src/utils/abortReasons.ts
  • src/utils/abortReasons.test.ts
  • src/utils/toolErrors.ts
  • src/tools/BashTool/BashTool.tsx
  • src/tools/BashTool/BashTool.errorOutput.test.ts
  • src/utils/Shell.ts
  • src/tools/PowerShellTool/PowerShellTool.tsx
  • src/utils/ShellCommand.ts
  • src/utils/errors.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.

Files:

  • src/utils/ShellCommand.test.ts
  • src/utils/toolErrors.test.ts
  • src/utils/abortReasons.ts
  • src/utils/abortReasons.test.ts
  • src/utils/toolErrors.ts
  • src/tools/BashTool/BashTool.tsx
  • src/tools/BashTool/BashTool.errorOutput.test.ts
  • src/utils/Shell.ts
  • src/tools/PowerShellTool/PowerShellTool.tsx
  • src/utils/ShellCommand.ts
  • src/utils/errors.ts
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}

⚙️ CodeRabbit configuration file

{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.

Files:

  • src/utils/ShellCommand.test.ts
  • src/utils/toolErrors.test.ts
  • src/utils/abortReasons.test.ts
  • src/tools/BashTool/BashTool.errorOutput.test.ts
**

⚙️ CodeRabbit configuration file

**: # AGENTS.md - AI Agent Coding Guide

This guide is for AI coding agents working in the OpenClaude repository. Read it before changing code, and also follow CONTRIBUTING.md for contributor policy, PR expectations, review follow-up, and project scope.

Project Snapshot

OpenClaude is a coding-agent CLI for cloud and local model providers. It supports OpenAI-compatible APIs, Anthropic, Gemini, DeepSeek, Ollama, MCP, local backends, slash commands, tools, agents, and a React/Ink terminal UI.

The installed CLI runs on Node.js >=22.0.0. Bun is used for source builds, scripts, dependency management, and tests.

Work Style

  • Keep changes focused on one problem.
  • Prefer existing patterns in the file or nearby module.
  • Avoid unrelated formatting, renames, dependency changes, or broad rewrites.
  • Add or update tests when behavior changes.
  • Update docs when setup, commands, provider behavior, or user-facing behavior changes.
  • For new features, larger refactors, dependencies, or runtime changes, follow the issue-first guidance in CONTRIBUTING.md.

Stack And Conventions

  • TypeScript with strict mode and ESM imports.
  • React + Ink for terminal UI.
  • Bun lockfile and Bun scripts for development workflows.
  • Node runtime for the built CLI.
  • Python exists for legacy/local-provider helper code. Do not add new Python code or expand Python-based features unless a maintainer explicitly approves that direction.

Common libraries and patterns:

  • chalk for terminal color.
  • commander for CLI argument parsing.
  • execa for child processes.
  • Existing service, provider, settings, permission, and UI patterns over new abstractions.

Repository Map

  • src/commands/ - slash and CLI command implementations.
  • src/components/ - React/Ink UI components.
  • src/services/ - API, MCP, OAuth, wiki, voice, and other service integrations.
  • src/tools/ - tool implementations.
  • src/utils/ - shared utilities.
  • `src/integration...

Files:

  • src/utils/ShellCommand.test.ts
  • src/utils/toolErrors.test.ts
  • src/utils/abortReasons.ts
  • src/utils/abortReasons.test.ts
  • src/utils/toolErrors.ts
  • src/tools/BashTool/BashTool.tsx
  • src/tools/BashTool/BashTool.errorOutput.test.ts
  • src/utils/Shell.ts
  • src/tools/PowerShellTool/PowerShellTool.tsx
  • src/utils/ShellCommand.ts
  • src/utils/errors.ts
src/{components/permissions,utils/permissions,hooks/toolPermission,tools,entrypoints/sdk}/**

⚙️ CodeRabbit configuration file

src/{components/permissions,utils/permissions,hooks/toolPermission,tools,entrypoints/sdk}/**: Review permission prompts, auto-allow logic, sandbox behavior, SDK permission schemas, shell/PowerShell execution, and background execution paths as security-sensitive. Block on bypasses, unclear trust boundaries, unsafe path handling, missing user visibility, or changes that broaden allowed behavior without an explicit maintainer decision.

Files:

  • src/tools/BashTool/BashTool.tsx
  • src/tools/BashTool/BashTool.errorOutput.test.ts
  • src/tools/PowerShellTool/PowerShellTool.tsx
🔇 Additional comments (33)
src/utils/abortReasons.ts (2)

1-20: LGTM!


26-46: LGTM!

src/utils/abortReasons.test.ts (1)

1-70: LGTM!

src/utils/ShellCommand.ts (7)

6-11: LGTM!

Also applies to: 36-50


158-171: LGTM!


228-241: LGTM!


329-395: LGTM!


397-404: LGTM!


471-519: LGTM!


521-548: LGTM!

src/utils/ShellCommand.test.ts (2)

40-78: LGTM!


100-100: LGTM!

src/utils/Shell.ts (3)

18-18: LGTM!


272-274: LGTM!


469-479: LGTM!

src/utils/errors.ts (1)

52-75: LGTM!

src/utils/toolErrors.ts (2)

5-10: LGTM!


28-37: LGTM!

src/utils/toolErrors.test.ts (3)

29-39: LGTM!


41-59: LGTM!


102-107: LGTM!

src/tools/BashTool/BashTool.tsx (5)

286-304: LGTM!


565-636: LGTM!


637-768: LGTM!


800-813: LGTM!


855-874: LGTM!

src/tools/BashTool/BashTool.errorOutput.test.ts (2)

70-97: LGTM!


99-123: LGTM!

src/tools/PowerShellTool/PowerShellTool.tsx (5)

252-266: LGTM!


393-450: LGTM!


452-604: LGTM!


656-669: LGTM!


670-683: LGTM!

Comment thread src/utils/abortReasons.ts
jatmn
jatmn previously approved these changes Jun 17, 2026

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for the contribution. I do not see any actionable issues from my review.

@kevincodex1 LGTM

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 2, 2026
@chioarub
chioarub requested a review from jatmn July 2, 2026 05:58

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for the contribution. I do not see any actionable issues from my review.

@kevincodex1 LGTM

@kevincodex1 kevincodex1 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@kevincodex1
kevincodex1 merged commit ac2b575 into Twigpine:main Jul 2, 2026
4 checks passed
hotmanxp pushed a commit to hotmanxp/openclaude that referenced this pull request Jul 3, 2026
* fix: classify shell aborts as cancellations

* fix: enumerate shell abort messages

* fix: preserve PowerShell large error output
@chioarub
chioarub deleted the pr/tool-bash-abort-semantics branch July 5, 2026 06:10
@coderabbitai coderabbitai Bot mentioned this pull request Jul 5, 2026
6 of 7 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants