Skip to content

fix(query): configure hard max and abort reasons - #1850

Merged
kevincodex1 merged 3 commits into
Twigpine:mainfrom
chioarub:fix/query-timeout-hard-max-config
Jul 5, 2026
Merged

kevincodex1 merged 3 commits into
Twigpine:mainfrom
chioarub:fix/query-timeout-hard-max-config

Conversation

@chioarub

@chioarub chioarub commented Jul 4, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Add OPENCLAUDE_QUERY_HARD_MAX_MS so long foreground query sessions can raise the QueryGuard hard maximum without editing source.
  • Classify aborts by explicit reason so query timeouts, hard maximums, backgrounding, and parent-task aborts are not surfaced as user interruptions.
  • Keep synthetic parent-abort tool results from tripping repeated-tool-failure detection while preserving real tool timeout failures.

Impact

  • user-facing impact: long-running sessions can opt into a larger foreground query hard maximum, and timeout/background abort messages identify the real cause.
  • developer/maintainer impact: abort reason formatting is centralized and covered across main query, stop hooks, API stream logging, and tool-result cleanup paths.

Testing

  • bun run build
  • bun run smoke
  • bun run check (not run; focused tests, typecheck, smoke/build, and PR intent scan were run instead)
  • focused tests:
    • bun test src/utils/queryGuardConfig.test.ts src/screens/REPL.queryLifecycle.test.ts src/utils/QueryGuard.test.ts src/utils/abortReasons.test.ts src/query.abortClassification.test.ts src/query/stopHooks.goal.test.ts src/query/toolFailureLoopGuard.test.ts src/services/api/claude.abortClassification.test.ts src/services/api/claude.lifecycle.test.ts src/services/api/claude.streamWatchdog.test.ts src/services/tools/StreamingToolExecutor.test.ts src/services/tools/toolExecution.test.ts
    • env ZDOTDIR=/tmp/openclaude-empty-zdotdir bun test src/services/tools/queryActivityLease.test.ts src/tools/BashTool/BashTool.errorOutput.test.ts src/utils/ShellCommand.test.ts src/utils/queryLifecycle.test.ts
    • bun run typecheck
    • bun run security:pr-scan
    • git diff --check

Notes

  • provider/model path tested: not provider-specific
  • screenshots attached: not applicable
  • follow-up work or known limitations: backgrounding now emits an explicit system warning instead of being silent.

Summary by CodeRabbit

  • New Features
    • Added configurable query hard-time limit via OPENCLAUDE_QUERY_HARD_MAX_MS.
    • Made query-guard configuration environment-driven in the REPL lifecycle.
  • Bug Fixes
    • Improved abort/timeout classification and messaging across streaming, tool execution, stop hooks, and REPL lifecycle logs.
    • Ensured “user interruption” transcript content and advisor/tool interruption events are emitted only for true user cancels.
    • Added support for additional abort normalization, including side-task cancellation.
  • Documentation
    • Documented OPENCLAUDE_QUERY_HARD_MAX_MS, including defaults and invalid-value handling.
  • Tests
    • Expanded coverage for abort classification, message gating, and reason-specific behaviors.

@coderabbitai

coderabbitai Bot commented Jul 4, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: fc1be14b-3a10-4ec6-8161-c9b69f0f563e

📥 Commits

Reviewing files that changed from the base of the PR and between dfff88b and d72d309.

📒 Files selected for processing (1)
  • src/query.abortClassification.test.ts
📜 Recent review details
⏰ Context from checks skipped due to timeout. (2)
  • GitHub Check: smoke-and-tests
  • GitHub Check: typecheck
🧰 Additional context used
📓 Path-based instructions (9)
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript with strict mode and ESM imports

Files:

  • src/query.abortClassification.test.ts
**/*.{ts,tsx,js,jsx,py,json,md}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Follow the existing code style in the touched files

Files:

  • src/query.abortClassification.test.ts
**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add or update tests when the change affects behavior

Files:

  • src/query.abortClassification.test.ts
**/*.test.{ts,tsx,js}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Test the exact provider/model path you changed when possible

Files:

  • src/query.abortClassification.test.ts
**/*.{ts,tsx,js,jsx,py}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Keep comments useful and concise

Files:

  • src/query.abortClassification.test.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

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

Files:

  • src/query.abortClassification.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.

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/integrations/ - provider and model integration metadata.
  • src/entrypoints/ - CLI, MCP, SDK, and generated public types.
  • src/tasks/ - local, remote, workflow, and monitor tas...

Files:

  • src/query.abortClassification.test.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/query.abortClassification.test.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/query.abortClassification.test.ts
🔇 Additional comments (1)
src/query.abortClassification.test.ts (1)

65-131: LGTM!


📝 Walkthrough

Walkthrough

This PR adds reason-aware abort messaging across query, tool, and Claude streaming paths, extends abort-reason normalization, and introduces OPENCLAUDE_QUERY_HARD_MAX_MS parsing and REPL wiring for QueryGuard.

Changes

Abort Reason Classification and Wiring

Layer / File(s) Summary
Abort reason helper functions
src/utils/abortReasons.ts, src/utils/abortReasons.test.ts
AbortReason gains side-task-cancelled; normalization and message helpers now cover side-task, timeout, and user-abort cases.
Query and stop-hooks abort messaging
src/query.ts, src/query.abortClassification.test.ts, src/query/stopHooks.ts, src/query/stopHooks.goal.test.ts, src/utils/queryLifecycle.ts, src/utils/queryLifecycle.test.ts
Aborted streaming, aborted tools, and stop-hook flows use normalized abort reasons to decide system messages and interruption transcript output; query terminal reason classification is added.
Tool failure loop guard synthetic abort filtering
src/query/toolFailureLoopGuard.ts, src/query/toolFailureLoopGuard.test.ts
Synthetic abort tool results are matched by derived prefixes, while tool-timeout remains a real failure signal.
Streaming tool abort handling
src/services/tools/StreamingToolExecutor.ts, src/services/tools/StreamingToolExecutor.test.ts, src/services/tools/toolExecution.ts, src/services/tools/toolExecution.test.ts
Streaming and already-aborted tool execution now produce structured, reason-aware abort results and corresponding tests cover the emitted tool-result text.
Claude streaming abort messaging
src/services/api/claude.ts, src/services/api/claude.abortClassification.test.ts
Claude stream abort logging uses shared abort-message helpers, and advisor interruption analytics are gated by reason-aware interruption classification.

Query Hard-Max Timeout Configuration

Layer / File(s) Summary
queryGuardConfig env parsing
src/utils/queryGuardConfig.ts, src/utils/queryGuardConfig.test.ts, docs/advanced-setup.md, src/utils/QueryGuard.test.ts
A new env parser reads OPENCLAUDE_QUERY_HARD_MAX_MS, validates bounds, warns on invalid values, documents the variable, and tests QueryGuard behavior against the configured hard max.
REPL and QueryGuard wiring
src/screens/REPL.tsx, src/screens/REPL.queryLifecycle.test.ts
REPL now builds QueryGuard from env-derived options, maps terminal reasons through normalized abort reasons, and propagates derived timeout abort reasons into lifecycle logs.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Suggested reviewers: jatmn, kevincodex1

🚥 Pre-merge checks | ✅ 7
✅ Passed checks (7 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and matches the main changes around query hard max configuration and abort-reason handling.
Description check ✅ Passed It follows the required sections and includes summary, impact, testing, and notes with concrete details.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 PASS: The PR notes backgrounding as a known limitation and the diff shows only abort/configuration changes; no blocker is called out.
No Hidden Policy Change ✅ Passed Changes are limited to explicit abort-classification, QueryGuard env config, and related messaging/telemetry; no hidden routing or permission-policy shift found.
✨ 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.

@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: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/screens/REPL.tsx (1)

564-581: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Missing direct test coverage for the new terminal-reason categorization.

The switch collapses background/parent-ended/side-task-cancelled into 'parent-ended' — a lifecycle-log/messaging behavior change. REPL.queryLifecycle.test.ts in this cohort only asserts QueryGuard construction wiring, not this function's branch behavior.

As per path instructions, tests should "add/update tests to cover the new behavior" for changed user-facing/lifecycle-logging behavior.

🤖 Prompt for 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.

In `@src/screens/REPL.tsx` around lines 564 - 581, Add direct test coverage for
getQueryTerminalReason in REPL.tsx, since the new abort-reason mapping is
user-facing lifecycle behavior. Update REPL.queryLifecycle.test.ts (or the
closest REPL query lifecycle test suite) to assert each branch: non-aborted
signals returning ok/unknown, query-timeout and hard-max-query-timeout
passthrough, user-abort and interrupt mapping to user-abort, and
background/parent-ended/side-task-cancelled mapping to parent-ended. Use the
existing getQueryTerminalReason and normalizeAbortReason behavior as the target
for the new assertions.
🤖 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/query.abortClassification.test.ts`:
- Around line 1-65: This test is asserting implementation text in query.ts
instead of the real abort behavior, so replace or supplement it with a
behavioral regression test. Use the existing generator flow in query.ts (and
mirror stopHooks.goal.test.ts) to mock an abortController, trigger
query-timeout/background/hard_max reasons, and assert the yielded
system/tool-result messages. Keep coverage focused on user-visible output, not
string presence like getQueryAbortSystemMessage or the removed Interrupted by
user literal.

In `@src/query.ts`:
- Around line 51-55: Fix the shared abort-reason gap by updating
normalizeAbortReason in utils/abortReasons so a legacy bare
AbortController.abort() still normalizes to the user-interruption text used by
getMissingToolResultAbortMessage. In query.ts, keep the abort classification
flow around abortReason, getQueryAbortSystemMessage, and
shouldCreateUserInterruptionMessage unchanged aside from relying on the
corrected normalization. The repeated abort-message block in query.ts and the
matching logic in stopHooks.ts can be left for a follow-up shared helper
refactor since the root-cause fix is in abortReasons.

In `@src/services/api/claude.abortClassification.test.ts`:
- Around line 1-13: The current grep-based test only verifies source substrings
and does not exercise the real abort-message behavior in claude.ts. Replace or
supplement it with a behavioral test that mocks the streaming abort path,
triggers an actual abort, and asserts on the resulting logForDebugging/logEvent
output and gating behavior. Use the claude.ts abort handling flow around
getStreamingAbortMessage and signal.reason to locate the code, and verify the
user-visible message rather than implementation text.

In `@src/utils/abortReasons.test.ts`:
- Around line 82-123: The abortReasons test currently covers the legacy
bare-abort signal only for shouldCreateUserInterruptionMessage, so extend the
same test to assert getMissingToolResultAbortMessage and
getStreamingAbortMessage with defaultAbort.signal.reason as well. Use the
existing abortReasons helper names in src/utils/abortReasons.test.ts to add
expectations that the bare-abort case stays consistent across all three
functions.

In `@src/utils/abortReasons.ts`:
- Around line 102-155: The abort reason normalization is missing the legacy bare
AbortController.abort() / AbortError case, causing
getMissingToolResultAbortMessage and getStreamingAbortMessage to classify it as
unknown instead of user abort. Update normalizeAbortReason so the DOMException
name === 'AbortError' path maps to the same user-abort signal used elsewhere,
then simplify shouldCreateUserInterruptionMessage to rely on
normalizeAbortReason only. This will make getMissingToolResultAbortMessage and
getStreamingAbortMessage return the correct user-facing messages consistently.

---

Outside diff comments:
In `@src/screens/REPL.tsx`:
- Around line 564-581: Add direct test coverage for getQueryTerminalReason in
REPL.tsx, since the new abort-reason mapping is user-facing lifecycle behavior.
Update REPL.queryLifecycle.test.ts (or the closest REPL query lifecycle test
suite) to assert each branch: non-aborted signals returning ok/unknown,
query-timeout and hard-max-query-timeout passthrough, user-abort and interrupt
mapping to user-abort, and background/parent-ended/side-task-cancelled mapping
to parent-ended. Use the existing getQueryTerminalReason and
normalizeAbortReason behavior as the target for the new assertions.
🪄 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

Run ID: 2ceb6eb6-59d7-4797-bd11-987248bcc561

📥 Commits

Reviewing files that changed from the base of the PR and between d1530c2 and c9c4379.

📒 Files selected for processing (20)
  • docs/advanced-setup.md
  • src/query.abortClassification.test.ts
  • src/query.ts
  • src/query/stopHooks.goal.test.ts
  • src/query/stopHooks.ts
  • src/query/toolFailureLoopGuard.test.ts
  • src/query/toolFailureLoopGuard.ts
  • src/screens/REPL.queryLifecycle.test.ts
  • src/screens/REPL.tsx
  • src/services/api/claude.abortClassification.test.ts
  • src/services/api/claude.ts
  • src/services/tools/StreamingToolExecutor.test.ts
  • src/services/tools/StreamingToolExecutor.ts
  • src/services/tools/toolExecution.test.ts
  • src/services/tools/toolExecution.ts
  • src/utils/QueryGuard.test.ts
  • src/utils/abortReasons.test.ts
  • src/utils/abortReasons.ts
  • src/utils/queryGuardConfig.test.ts
  • src/utils/queryGuardConfig.ts
📜 Review details
⚠️ CI failures not shown inline (2)

GitHub Actions: PR Checks / smoke-and-tests: fix(query): configure hard max and abort reasons

Conclusion: failure

View job details

ored tip catalog > all tips have unique sponsor-prefixed ids [1.00ms]
 (pass) sponsored tip catalog > rendered content embeds sponsor name, tip body, and URL
 (pass) sponsored tip catalog > Xiaomi MiMo tips render through sponsored tip chrome [1.00ms]
 (pass) sponsored tip catalog > isRelevant follows sponsoredTipsEnabled [1.00ms]
 (pass) sponsored history tracking > records lastShownAt and increments totalShown [1.00ms]
 (pass) sponsored history tracking > getSessionsSinceLastSponsored returns Infinity when never shown [1.00ms]
 (pass) sponsored history tracking > getSessionsSinceLastSponsored returns delta from current startups
 ##[endgroup]
 ##[group]src/services/compact/microCompact.test.ts:
 (pass) microCompact MCP tool compaction > module exports load correctly [1.00ms]
 (pass) microCompact MCP tool compaction > estimateMessageTokens counts MCP tool_use blocks
 (pass) microCompact MCP tool compaction > microcompactMessages processes MCP tools without error
 (pass) microCompact MCP tool compaction > microcompactMessages processes mixed built-in and MCP tools [1.00ms]
 (pass) microCompact MCP tool compaction > time-based microcompact clears native toolUseResult for old compacted results
 ##[endgroup]
 ##[group]src/services/compact/snipProjection.test.ts:
 (pass) isSnipBoundaryMessage > returns true for message with snipMetadata
 (pass) isSnipBoundaryMessage > returns false for compact_boundary without snipMetadata
 (pass) isSnipBoundaryMessage > returns false for regular message
 (pass) isSnipBoundaryMessage > returns false for null/undefined
 (pass) projectSnippedView > returns original array when no snip boundaries present
 (pass) projectSnippedView > removes messages whose UUIDs appear in snipMetadata.removedUuids
 (pass) projectSnippedView > accumulates removedUuids from multiple snip boundaries
 (pass) projectSnippedView > handles boundaries with no removedUuids gracefully
 (pass) projectSnippedView > prunes earlier messages when the boundary is appended...

GitHub Actions: PR Checks / 2_smoke-and-tests.txt: fix(query): configure hard max and abort reasons

Conclusion: failure

View job details

truncated structured Bash JSON in streaming responses [2.00ms]
 (pass) does not normalize incomplete streamed Bash commands when finish_reason is length [1.00ms]
 (pass) repairs truncated JSON objects even without command field [1.00ms]
 (pass) preserves raw input for unknown plain string tool arguments [1.00ms]
 (pass) preserves parsed string input for unknown JSON string tool arguments [2.00ms]
 (pass) sanitizes malformed MCP tool schemas before sending them to OpenAI [1.00ms]
 (pass) optional tool properties are not added to required[] — fixes Groq/Azure 400 tool_use_failed [2.00ms]
 (pass) coalesces consecutive user messages to avoid alternation errors (issue `#202`) [1.00ms]
 (pass) coalesces consecutive assistant messages preserving tool_calls (issue `#202`) [1.00ms]
 (pass) non-streaming: reasoning_content emitted as thinking block only when content is null [1.00ms]
 (pass) non-streaming: empty string content does not fall through to reasoning_content as text [2.00ms]
 (pass) non-streaming: real content takes precedence over reasoning_content [1.00ms]
 (pass) non-streaming: preserves response body when usage parsing fails [1.00ms]
 (pass) non-streaming: preserves response.url routing metadata after body read [1.00ms]
 (pass) non-streaming: strips <think> tag block from assistant content [1.00ms]
 (pass) streaming: thinking block closed before tool call [1.00ms]
 (pass) streaming: strips <think> tag block from assistant content deltas [2.00ms]
 (pass) streaming: strips <think> tag split across multiple content chunks [1.00ms]
 (pass) streaming: preserves prose without tags (no phrase-based false positive) [1.00ms]
 (pass) strips credentials and query params from URL in fetch network error message [1.00ms]
 (pass) classifies localhost transport failures with actionable category marker [2.00ms]
 (pass) transport failures are not labeled with HTTP status 503 [1.00ms]
 (pass) propagates AbortError without wrapping it as transport failure [1.00ms]
 (pass) classifies...
🧰 Additional context used
📓 Path-based instructions (15)
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript with strict mode and ESM imports

Files:

  • src/query.abortClassification.test.ts
  • src/services/api/claude.abortClassification.test.ts
  • src/query/stopHooks.goal.test.ts
  • src/utils/queryGuardConfig.ts
  • src/screens/REPL.queryLifecycle.test.ts
  • src/utils/queryGuardConfig.test.ts
  • src/utils/QueryGuard.test.ts
  • src/services/tools/toolExecution.ts
  • src/services/tools/toolExecution.test.ts
  • src/services/tools/StreamingToolExecutor.test.ts
  • src/query/stopHooks.ts
  • src/utils/abortReasons.test.ts
  • src/services/api/claude.ts
  • src/query/toolFailureLoopGuard.ts
  • src/query/toolFailureLoopGuard.test.ts
  • src/query.ts
  • src/screens/REPL.tsx
  • src/services/tools/StreamingToolExecutor.ts
  • src/utils/abortReasons.ts
**/*.{ts,tsx,js,jsx,py,json,md}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Follow the existing code style in the touched files

Files:

  • src/query.abortClassification.test.ts
  • docs/advanced-setup.md
  • src/services/api/claude.abortClassification.test.ts
  • src/query/stopHooks.goal.test.ts
  • src/utils/queryGuardConfig.ts
  • src/screens/REPL.queryLifecycle.test.ts
  • src/utils/queryGuardConfig.test.ts
  • src/utils/QueryGuard.test.ts
  • src/services/tools/toolExecution.ts
  • src/services/tools/toolExecution.test.ts
  • src/services/tools/StreamingToolExecutor.test.ts
  • src/query/stopHooks.ts
  • src/utils/abortReasons.test.ts
  • src/services/api/claude.ts
  • src/query/toolFailureLoopGuard.ts
  • src/query/toolFailureLoopGuard.test.ts
  • src/query.ts
  • src/screens/REPL.tsx
  • src/services/tools/StreamingToolExecutor.ts
  • src/utils/abortReasons.ts
**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add or update tests when the change affects behavior

Files:

  • src/query.abortClassification.test.ts
  • src/services/api/claude.abortClassification.test.ts
  • src/query/stopHooks.goal.test.ts
  • src/screens/REPL.queryLifecycle.test.ts
  • src/utils/queryGuardConfig.test.ts
  • src/utils/QueryGuard.test.ts
  • src/services/tools/toolExecution.test.ts
  • src/services/tools/StreamingToolExecutor.test.ts
  • src/utils/abortReasons.test.ts
  • src/query/toolFailureLoopGuard.test.ts
**/*.test.{ts,tsx,js}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Test the exact provider/model path you changed when possible

Files:

  • src/query.abortClassification.test.ts
  • src/services/api/claude.abortClassification.test.ts
  • src/query/stopHooks.goal.test.ts
  • src/screens/REPL.queryLifecycle.test.ts
  • src/utils/queryGuardConfig.test.ts
  • src/utils/QueryGuard.test.ts
  • src/services/tools/toolExecution.test.ts
  • src/services/tools/StreamingToolExecutor.test.ts
  • src/utils/abortReasons.test.ts
  • src/query/toolFailureLoopGuard.test.ts
**/*.{ts,tsx,js,jsx,py}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Keep comments useful and concise

Files:

  • src/query.abortClassification.test.ts
  • src/services/api/claude.abortClassification.test.ts
  • src/query/stopHooks.goal.test.ts
  • src/utils/queryGuardConfig.ts
  • src/screens/REPL.queryLifecycle.test.ts
  • src/utils/queryGuardConfig.test.ts
  • src/utils/QueryGuard.test.ts
  • src/services/tools/toolExecution.ts
  • src/services/tools/toolExecution.test.ts
  • src/services/tools/StreamingToolExecutor.test.ts
  • src/query/stopHooks.ts
  • src/utils/abortReasons.test.ts
  • src/services/api/claude.ts
  • src/query/toolFailureLoopGuard.ts
  • src/query/toolFailureLoopGuard.test.ts
  • src/query.ts
  • src/screens/REPL.tsx
  • src/services/tools/StreamingToolExecutor.ts
  • src/utils/abortReasons.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

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

Files:

  • src/query.abortClassification.test.ts
  • src/services/api/claude.abortClassification.test.ts
  • src/query/stopHooks.goal.test.ts
  • src/utils/queryGuardConfig.ts
  • src/screens/REPL.queryLifecycle.test.ts
  • src/utils/queryGuardConfig.test.ts
  • src/utils/QueryGuard.test.ts
  • src/services/tools/toolExecution.ts
  • src/services/tools/toolExecution.test.ts
  • src/services/tools/StreamingToolExecutor.test.ts
  • src/query/stopHooks.ts
  • src/utils/abortReasons.test.ts
  • src/services/api/claude.ts
  • src/query/toolFailureLoopGuard.ts
  • src/query/toolFailureLoopGuard.test.ts
  • src/query.ts
  • src/screens/REPL.tsx
  • src/services/tools/StreamingToolExecutor.ts
  • src/utils/abortReasons.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.

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/integrations/ - provider and model integration metadata.
  • src/entrypoints/ - CLI, MCP, SDK, and generated public types.
  • src/tasks/ - local, remote, workflow, and monitor tas...

Files:

  • src/query.abortClassification.test.ts
  • docs/advanced-setup.md
  • src/services/api/claude.abortClassification.test.ts
  • src/query/stopHooks.goal.test.ts
  • src/utils/queryGuardConfig.ts
  • src/screens/REPL.queryLifecycle.test.ts
  • src/utils/queryGuardConfig.test.ts
  • src/utils/QueryGuard.test.ts
  • src/services/tools/toolExecution.ts
  • src/services/tools/toolExecution.test.ts
  • src/services/tools/StreamingToolExecutor.test.ts
  • src/query/stopHooks.ts
  • src/utils/abortReasons.test.ts
  • src/services/api/claude.ts
  • src/query/toolFailureLoopGuard.ts
  • src/query/toolFailureLoopGuard.test.ts
  • src/query.ts
  • src/screens/REPL.tsx
  • src/services/tools/StreamingToolExecutor.ts
  • src/utils/abortReasons.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/query.abortClassification.test.ts
  • docs/advanced-setup.md
  • src/services/api/claude.abortClassification.test.ts
  • src/query/stopHooks.goal.test.ts
  • src/utils/queryGuardConfig.ts
  • src/screens/REPL.queryLifecycle.test.ts
  • src/utils/queryGuardConfig.test.ts
  • src/utils/QueryGuard.test.ts
  • src/services/tools/toolExecution.ts
  • src/services/tools/toolExecution.test.ts
  • src/services/tools/StreamingToolExecutor.test.ts
  • src/query/stopHooks.ts
  • src/utils/abortReasons.test.ts
  • src/services/api/claude.ts
  • src/query/toolFailureLoopGuard.ts
  • src/query/toolFailureLoopGuard.test.ts
  • src/query.ts
  • src/screens/REPL.tsx
  • src/services/tools/StreamingToolExecutor.ts
  • src/utils/abortReasons.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/query.abortClassification.test.ts
  • src/services/api/claude.abortClassification.test.ts
  • src/query/stopHooks.goal.test.ts
  • src/screens/REPL.queryLifecycle.test.ts
  • src/utils/queryGuardConfig.test.ts
  • src/utils/QueryGuard.test.ts
  • src/services/tools/toolExecution.test.ts
  • src/services/tools/StreamingToolExecutor.test.ts
  • src/utils/abortReasons.test.ts
  • src/query/toolFailureLoopGuard.test.ts
docs/**/*.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Update docs when setup, commands, or user-facing behavior changes

Files:

  • docs/advanced-setup.md
{README.md,CONTRIBUTING.md,docs/**,.github/pull_request_template.md}

⚙️ CodeRabbit configuration file

{README.md,CONTRIBUTING.md,docs/**,.github/pull_request_template.md}: Review docs for accuracy against current code behavior. Flag security or provider claims that overpromise, stale install commands, missing setup caveats, and instructions that could push users toward unsafe credential handling. Keep purely wording-level suggestions non-blocking.

Files:

  • docs/advanced-setup.md
{src/commands/**/*.ts,src/services/**/*.ts,src/entrypoints/**/*.ts}

📄 CodeRabbit inference engine (AGENTS.md)

Use chalk for terminal color in CLI code

Files:

  • src/services/api/claude.abortClassification.test.ts
  • src/services/tools/toolExecution.ts
  • src/services/tools/toolExecution.test.ts
  • src/services/tools/StreamingToolExecutor.test.ts
  • src/services/api/claude.ts
  • src/services/tools/StreamingToolExecutor.ts
{src/services/**/*.ts,src/utils/**/*.ts}

📄 CodeRabbit inference engine (AGENTS.md)

Use execa for child processes

Files:

  • src/services/api/claude.abortClassification.test.ts
  • src/utils/queryGuardConfig.ts
  • src/utils/queryGuardConfig.test.ts
  • src/utils/QueryGuard.test.ts
  • src/services/tools/toolExecution.ts
  • src/services/tools/toolExecution.test.ts
  • src/services/tools/StreamingToolExecutor.test.ts
  • src/utils/abortReasons.test.ts
  • src/services/api/claude.ts
  • src/services/tools/StreamingToolExecutor.ts
  • src/utils/abortReasons.ts
{src/integrations/**/*.ts,src/services/**/*.ts}

📄 CodeRabbit inference engine (AGENTS.md)

Test the exact provider/model path you changed when possible for provider modifications

Files:

  • src/services/api/claude.abortClassification.test.ts
  • src/services/tools/toolExecution.ts
  • src/services/tools/toolExecution.test.ts
  • src/services/tools/StreamingToolExecutor.test.ts
  • src/services/api/claude.ts
  • src/services/tools/StreamingToolExecutor.ts
{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}

⚙️ CodeRabbit configuration file

{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}: Review provider routing, model selection, env precedence, auth/token handling, OpenAI-compatible shims, retries, proxy behavior, and outbound HTTP behavior with high scrutiny. Block on silent default changes, hidden fallback expansion, credential reuse mistakes, hardcoded provider assumptions, or new network reach that is not intentional and documented.

Files:

  • src/services/api/claude.abortClassification.test.ts
  • src/services/api/claude.ts
🔇 Additional comments (21)
src/utils/queryGuardConfig.ts (1)

1-67: LGTM!

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

1-79: LGTM!

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

2-2: LGTM!

Also applies to: 350-391

src/screens/REPL.tsx (2)

38-40: LGTM!

Also applies to: 1011-1015


1817-1822: 🎯 Functional Correctness

No issue here: timeout reasons already map to canonical abort reasons. The timeout path only produces query-timeout or hard-max-query-timeout, and both are accepted by normalizeAbortReason, so this does not degrade to unknown-abort.

			> Likely an incorrect or invalid review comment.
src/screens/REPL.queryLifecycle.test.ts (1)

26-32: LGTM!

docs/advanced-setup.md (1)

397-397: 🗄️ Data Integrity & Integration

No change needed The documented default matches DEFAULT_QUERY_HARD_MAX_MS (30 * 60 * 1000).

			> Likely an incorrect or invalid review comment.
src/query/stopHooks.ts (1)

20-23: Logic mirrors the (already flagged) query.ts pattern; same optional dedup suggestion applies here, not repeating separately.

Also applies to: 323-334

src/utils/abortReasons.ts (2)

1-73: LGTM!


134-155: 🗄️ Data Integrity & Integration

No change needed tool-timeout is already excluded from SYNTHETIC_ABORT_TOOL_RESULT_PREFIXES, so real tool timeouts still count toward repeated-failure detection.

			> Likely an incorrect or invalid review comment.
src/query/stopHooks.goal.test.ts (1)

247-352: LGTM!

src/services/api/claude.ts (2)

60-63: LGTM!

Also applies to: 2629-2641


2664-2664: 🩺 Stability & Availability

No issue here: the SDK-timeout path already logs separately, and getStreamingAbortMessage only runs when signal.aborted is true.

			> Likely an incorrect or invalid review comment.
src/query/toolFailureLoopGuard.ts (1)

4-18: LGTM!

Also applies to: 343-345

src/query/toolFailureLoopGuard.test.ts (1)

4-4: LGTM!

Also applies to: 177-183, 202-244

src/services/tools/StreamingToolExecutor.ts (3)

12-15: LGTM (aside from the narrowing issue flagged above).

Also applies to: 38-41, 221-252


257-283: LGTM!


182-220: 🎯 Functional Correctness

No change needed here

reason === 'parent_abort' still narrows syntheticReason, so syntheticReason.abortReason is valid.

			> Likely an incorrect or invalid review comment.
src/services/tools/StreamingToolExecutor.test.ts (1)

28-44: LGTM!

Also applies to: 245-307

src/services/tools/toolExecution.ts (1)

65-68: LGTM!

Also applies to: 139-145, 486-488, 517-521

src/services/tools/toolExecution.test.ts (1)

20-20: LGTM!

Also applies to: 38-54, 527-577

Comment thread src/query.abortClassification.test.ts
Comment thread src/query.ts
Comment thread src/services/api/claude.abortClassification.test.ts
Comment thread src/utils/abortReasons.test.ts
Comment thread src/utils/abortReasons.ts

@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/query.abortClassification.test.ts`:
- Around line 65-142: Extract the repeated QueryParams setup shared by
makeParams and makeToolAbortParams into a common helper so the duplicated
messages, systemPrompt, canUseTool, querySource, agentStepLimit, and deps
boilerplate live in one place. Keep the per-test differences localized by
letting the helper accept the varying pieces, especially deps.callModel and the
tool/toolUseContext setup used by makeToolAbortParams. Use the existing
makeParams and makeToolAbortParams symbols as the main entry points and preserve
the current test behavior while removing the repeated scaffolding.
🪄 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

Run ID: c4d4f1c7-4d0d-4547-9f0e-e8d9452cfd70

📥 Commits

Reviewing files that changed from the base of the PR and between c9c4379 and dfff88b.

📒 Files selected for processing (8)
  • src/query.abortClassification.test.ts
  • src/screens/REPL.tsx
  • src/services/api/claude.abortClassification.test.ts
  • src/services/api/claude.ts
  • src/utils/abortReasons.test.ts
  • src/utils/abortReasons.ts
  • src/utils/queryLifecycle.test.ts
  • src/utils/queryLifecycle.ts
📜 Review details
⚠️ CI failures not shown inline (2)

GitHub Actions: PR Checks / smoke-and-tests: fix(query): configure hard max and abort reasons

Conclusion: failure

View job details

Xiaomi MiMo tips [1.00ms]
 (pass) sponsored tip catalog > all tips have unique sponsor-prefixed ids [1.00ms]
 (pass) sponsored tip catalog > rendered content embeds sponsor name, tip body, and URL [1.00ms]
 (pass) sponsored tip catalog > Xiaomi MiMo tips render through sponsored tip chrome
 (pass) sponsored tip catalog > isRelevant follows sponsoredTipsEnabled [1.00ms]
 (pass) sponsored history tracking > records lastShownAt and increments totalShown [1.00ms]
 (pass) sponsored history tracking > getSessionsSinceLastSponsored returns Infinity when never shown [1.00ms]
 (pass) sponsored history tracking > getSessionsSinceLastSponsored returns delta from current startups
 ##[endgroup]
 ##[group]src/services/compact/microCompact.test.ts:
 (pass) microCompact MCP tool compaction > module exports load correctly
 (pass) microCompact MCP tool compaction > estimateMessageTokens counts MCP tool_use blocks
 (pass) microCompact MCP tool compaction > microcompactMessages processes MCP tools without error
 (pass) microCompact MCP tool compaction > microcompactMessages processes mixed built-in and MCP tools
 (pass) microCompact MCP tool compaction > time-based microcompact clears native toolUseResult for old compacted results [1.00ms]
 ##[endgroup]
 ##[group]src/services/compact/snipProjection.test.ts:
 (pass) isSnipBoundaryMessage > returns true for message with snipMetadata
 (pass) isSnipBoundaryMessage > returns false for compact_boundary without snipMetadata
 (pass) isSnipBoundaryMessage > returns false for regular message
 (pass) isSnipBoundaryMessage > returns false for null/undefined
 (pass) projectSnippedView > returns original array when no snip boundaries present
 (pass) projectSnippedView > removes messages whose UUIDs appear in snipMetadata.removedUuids
 (pass) projectSnippedView > accumulates removedUuids from multiple snip boundaries
 (pass) projectSnippedView > handles boundaries with no removedUuids gracefully [1.00ms]
 (pass) projectSnippedView > prunes earlier...

GitHub Actions: PR Checks / 1_smoke-and-tests.txt: fix(query): configure hard max and abort reasons

Conclusion: failure

View job details

rguments that begin with bracket syntax [2.00ms]
 (pass) normalizes streaming Bash arguments when the first chunk is only an opening brace [1.00ms]
 (pass) repairs truncated structured Bash JSON in streaming responses [3.00ms]
 (pass) does not normalize incomplete streamed Bash commands when finish_reason is length
 (pass) repairs truncated JSON objects even without command field [2.00ms]
 (pass) preserves raw input for unknown plain string tool arguments
 (pass) preserves parsed string input for unknown JSON string tool arguments [2.00ms]
 (pass) sanitizes malformed MCP tool schemas before sending them to OpenAI [2.00ms]
 (pass) optional tool properties are not added to required[] — fixes Groq/Azure 400 tool_use_failed [1.00ms]
 (pass) coalesces consecutive user messages to avoid alternation errors (issue `#202`) [2.00ms]
 (pass) coalesces consecutive assistant messages preserving tool_calls (issue `#202`) [2.00ms]
 (pass) non-streaming: reasoning_content emitted as thinking block only when content is null
 (pass) non-streaming: empty string content does not fall through to reasoning_content as text [1.00ms]
 (pass) non-streaming: real content takes precedence over reasoning_content [2.00ms]
 (pass) non-streaming: preserves response body when usage parsing fails [1.00ms]
 (pass) non-streaming: preserves response.url routing metadata after body read [1.00ms]
 (pass) non-streaming: strips <think> tag block from assistant content [2.00ms]
 (pass) streaming: thinking block closed before tool call [3.00ms]
 (pass) streaming: strips <think> tag block from assistant content deltas [1.00ms]
 (pass) streaming: strips <think> tag split across multiple content chunks [1.00ms]
 (pass) streaming: preserves prose without tags (no phrase-based false positive) [3.00ms]
 (pass) strips credentials and query params from URL in fetch network error message
 (pass) classifies localhost transport failures with actionable category marker [3.00ms]
 (pass) transport failures are not labeled ...
🧰 Additional context used
📓 Path-based instructions (13)
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use TypeScript with strict mode and ESM imports

Files:

  • src/services/api/claude.abortClassification.test.ts
  • src/utils/queryLifecycle.test.ts
  • src/utils/abortReasons.test.ts
  • src/utils/queryLifecycle.ts
  • src/query.abortClassification.test.ts
  • src/services/api/claude.ts
  • src/utils/abortReasons.ts
  • src/screens/REPL.tsx
{src/commands/**/*.ts,src/services/**/*.ts,src/entrypoints/**/*.ts}

📄 CodeRabbit inference engine (AGENTS.md)

Use chalk for terminal color in CLI code

Files:

  • src/services/api/claude.abortClassification.test.ts
  • src/services/api/claude.ts
{src/services/**/*.ts,src/utils/**/*.ts}

📄 CodeRabbit inference engine (AGENTS.md)

Use execa for child processes

Files:

  • src/services/api/claude.abortClassification.test.ts
  • src/utils/queryLifecycle.test.ts
  • src/utils/abortReasons.test.ts
  • src/utils/queryLifecycle.ts
  • src/services/api/claude.ts
  • src/utils/abortReasons.ts
{src/integrations/**/*.ts,src/services/**/*.ts}

📄 CodeRabbit inference engine (AGENTS.md)

Test the exact provider/model path you changed when possible for provider modifications

Files:

  • src/services/api/claude.abortClassification.test.ts
  • src/services/api/claude.ts
**/*.{ts,tsx,js,jsx,py,json,md}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Follow the existing code style in the touched files

Files:

  • src/services/api/claude.abortClassification.test.ts
  • src/utils/queryLifecycle.test.ts
  • src/utils/abortReasons.test.ts
  • src/utils/queryLifecycle.ts
  • src/query.abortClassification.test.ts
  • src/services/api/claude.ts
  • src/utils/abortReasons.ts
  • src/screens/REPL.tsx
**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Add or update tests when the change affects behavior

Files:

  • src/services/api/claude.abortClassification.test.ts
  • src/utils/queryLifecycle.test.ts
  • src/utils/abortReasons.test.ts
  • src/query.abortClassification.test.ts
**/*.test.{ts,tsx,js}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Test the exact provider/model path you changed when possible

Files:

  • src/services/api/claude.abortClassification.test.ts
  • src/utils/queryLifecycle.test.ts
  • src/utils/abortReasons.test.ts
  • src/query.abortClassification.test.ts
**/*.{ts,tsx,js,jsx,py}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Keep comments useful and concise

Files:

  • src/services/api/claude.abortClassification.test.ts
  • src/utils/queryLifecycle.test.ts
  • src/utils/abortReasons.test.ts
  • src/utils/queryLifecycle.ts
  • src/query.abortClassification.test.ts
  • src/services/api/claude.ts
  • src/utils/abortReasons.ts
  • src/screens/REPL.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

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

Files:

  • src/services/api/claude.abortClassification.test.ts
  • src/utils/queryLifecycle.test.ts
  • src/utils/abortReasons.test.ts
  • src/utils/queryLifecycle.ts
  • src/query.abortClassification.test.ts
  • src/services/api/claude.ts
  • src/utils/abortReasons.ts
  • src/screens/REPL.tsx
**

⚙️ 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.

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/integrations/ - provider and model integration metadata.
  • src/entrypoints/ - CLI, MCP, SDK, and generated public types.
  • src/tasks/ - local, remote, workflow, and monitor tas...

Files:

  • src/services/api/claude.abortClassification.test.ts
  • src/utils/queryLifecycle.test.ts
  • src/utils/abortReasons.test.ts
  • src/utils/queryLifecycle.ts
  • src/query.abortClassification.test.ts
  • src/services/api/claude.ts
  • src/utils/abortReasons.ts
  • src/screens/REPL.tsx
**/*

⚙️ 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/services/api/claude.abortClassification.test.ts
  • src/utils/queryLifecycle.test.ts
  • src/utils/abortReasons.test.ts
  • src/utils/queryLifecycle.ts
  • src/query.abortClassification.test.ts
  • src/services/api/claude.ts
  • src/utils/abortReasons.ts
  • src/screens/REPL.tsx
{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}

⚙️ CodeRabbit configuration file

{src/services/api/**,src/integrations/**,src/utils/model/**,src/utils/provider*.ts,src/commands/provider/**}: Review provider routing, model selection, env precedence, auth/token handling, OpenAI-compatible shims, retries, proxy behavior, and outbound HTTP behavior with high scrutiny. Block on silent default changes, hidden fallback expansion, credential reuse mistakes, hardcoded provider assumptions, or new network reach that is not intentional and documented.

Files:

  • src/services/api/claude.abortClassification.test.ts
  • src/services/api/claude.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/services/api/claude.abortClassification.test.ts
  • src/utils/queryLifecycle.test.ts
  • src/utils/abortReasons.test.ts
  • src/query.abortClassification.test.ts
🔇 Additional comments (9)
src/services/api/claude.ts (1)

60-63: LGTM!

Also applies to: 808-814, 2636-2645, 2668-2668

src/services/api/claude.abortClassification.test.ts (1)

1-58: LGTM! The previously flagged grep-based test concern is resolved — these tests now exercise real getClaudeStreamingAbortLogMessage/shouldCreateUserInterruptionMessage behavior against actual reason values and a real AbortController, rather than asserting on source text.

src/screens/REPL.tsx (1)

40-40: LGTM!

src/utils/abortReasons.ts (2)

42-56: Legacy AbortError case now handled — resolves prior gap.

normalizeAbortReason now maps a bare AbortController.abort() (name === 'AbortError') to 'user-abort', and shouldCreateUserInterruptionMessage correctly derives from it. This fixes the previously flagged mismatch where getMissingToolResultAbortMessage/getStreamingAbortMessage fell through to 'unknown-abort' for this path.

Also applies to: 111-113


62-153: LGTM!

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

31-46: Test coverage gap from prior review now closed.

Added assertions for getMissingToolResultAbortMessage/getStreamingAbortMessage against the legacy bare-abort() signal, matching what was requested previously.

Also applies to: 95-146

src/query.abortClassification.test.ts (1)

1-260: Behavioral rewrite resolves prior "source-text pattern matching" concern.

Tests now drive the real query() generator and assert on yielded tool-result/system/interruption messages, mirroring stopHooks.goal.test.ts. This is a solid improvement over the previous string-matching approach.

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

32-96: LGTM!

src/utils/queryLifecycle.ts (1)

1-2: LGTM!

Also applies to: 71-91

Comment thread src/query.abortClassification.test.ts Outdated

@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 5226fb9 into Twigpine:main Jul 5, 2026
4 checks passed
@chioarub
chioarub deleted the fix/query-timeout-hard-max-config branch July 5, 2026 05:44
hotmanxp added a commit to hotmanxp/openclaude that referenced this pull request Jul 5, 2026
Configure hard max query duration via OPENCLAUDE_QUERY_HARD_MAX_MS env var,
classify abort signals (AbortError/TimeoutError) into specific reasons, and
wire abort-reason system messages into stop hooks.

Co-Authored-By: Claude <noreply@anthropic.com>
hotmanxp added a commit to hotmanxp/openclaude that referenced this pull request Jul 5, 2026
Configure hard max query duration via OPENCLAUDE_QUERY_HARD_MAX_MS env var,
classify abort signals (AbortError/TimeoutError) into specific reasons, and
wire abort-reason system messages into stop hooks.

Co-Authored-By: Claude <noreply@anthropic.com>
@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