Skip to content

Conversation

@acoliver
Copy link
Collaborator

@acoliver acoliver commented Jan 6, 2026

Overview

This PR adds CLI configuration support for tool-level timeouts as requested in issue #920. The commit adds the CLI settings surface for users to configure timeout defaults and limits for the task (TaskTool) and run_shell_command (ShellTool) tools.

Background

Issue #920 requested the ability to add tool-level timeouts for the task and shell tools. The core implementation was already complete in packages/core/src/tools/task.ts and packages/core/src/tools/shell.ts, which supports:

  • Optional timeout_ms parameter on tool invocations
  • -1 value for YOLO mode (unlimited/no timeout)
  • Default timeout when parameter is omitted
  • Maximum timeout enforcement (clamping)
  • Reading defaults from ephemeral settings

What was missing: The CLI did not expose the ephemeral settings that allow users to configure these timeout values.

Changes Made

CLI Settings (packages/cli/src/settings/ephemeralSettings.ts)

  • Added 4 new ephemeral setting keys with help text:

    • task_default_timeout_ms: Default timeout for task tool
    • task_max_timeout_ms: Maximum allowed timeout for task tool
    • shell_default_timeout_ms: Default timeout for shell tool
    • shell_max_timeout_ms: Maximum allowed timeout for shell tool
  • Added validation logic: Accepts positive integers OR -1 for unlimited, rejects other negatives, zero, non-integers

Tests (packages/cli/src/ui/commands/setCommand.test.ts)

  • Added 3 new test cases for validation of timeout settings
  • Updated invalid-keys test to include the 4 new timeout keys

Documentation (docs/settings-and-profiles.md)

  • Added documentation for the 4 new timeout settings

closes #920

Summary by CodeRabbit

  • New Features

    • Four new timeout settings for shell and task (defaults: 120s, max: 600s); accept integers or -1 (unlimited).
    • Tools now support an optional per-invocation timeout parameter.
  • Documentation

    • Added CLI examples and a “Tool timeout settings” section with commands to configure timeouts.
  • Tests

    • Expanded runtime and tool tests to cover timeout validation, behavior, clamping, unlimited (-1), and error paths.

✏️ Tip: You can customize this high-level summary in your review settings.

@github-actions github-actions bot added the maintainer:e2e:ok Trusted contributor; maintainer-approved E2E run label Jan 6, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 6, 2026

Walkthrough

Adds per-call and ephemeral timeouts for shell and task tools: new ephemeral keys, CLI parsing/validation, tool parameter timeout_ms for ShellTool and TaskTool, AbortController-based timeout enforcement (including clamp/unlimited semantics), and tests for default, clamp, unlimited (-1), timeout, and abort paths.

Changes

Cohort / File(s) Summary
Documentation
docs/settings-and-profiles.md
Added four ephemeral settings and CLI examples: shell_default_timeout_ms, shell_max_timeout_ms, task_default_timeout_ms, task_max_timeout_ms with updated default/max values and example /set commands.
CLI settings & parsing
packages/cli/src/settings/ephemeralSettings.ts
Added the four new ephemeral keys to ephemeralSettingHelp and validEphemeralKeys; extended parseEphemeralSettingValue to validate integer values, allow -1 for unlimited, and require positive values otherwise.
CLI runtime tests
packages/cli/src/ui/commands/setCommand.test.ts
Expanded integration tests to cover numeric timeout values, -1 unlimited handling, and invalid inputs (negative < -1, zero, non-numeric, decimal) for the four new keys; updated valid-keys expectations.
Shell tool implementation & tests
packages/core/src/tools/shell.ts, packages/core/src/tools/shell.test.ts
Added timeout_ms?: number to ShellToolParams; resolve effective timeout via ephemeral config; create timer AbortController and combine with user signal; enforce clamp/unlimited semantics; produce distinct TIMEOUT vs abort results and include partial output; added tests for timeout and abort behaviors.
Task tool implementation & tests
packages/core/src/tools/task.ts, packages/core/src/tools/task.test.ts
Added timeout_ms?: number to TaskToolParams; TaskToolInvocation now receives Config; added timeout resolution, controllers, and propagation to orchestrator.launch; produce TIMEOUT results with partial output and updated abort/error handling; expanded tests for timeout and streaming behavior.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Config
  participant Tool as Shell/Task Tool
  participant Exec as ExecutionService/Orchestrator

  Client->>Tool: invoke run(..., timeout_ms?)
  Tool->>Config: read ephemeral defaults/max (`*_timeout_ms`)
  Note right of Tool: resolveTimeoutMs (use default, clamp to max, -1 = unlimited)
  alt timeout configured (not unlimited)
    Tool->>Tool: create AbortController + timer
    Tool->>Exec: launch(..., signal: combinedSignal)
    par execution runs
      Exec->>Exec: stream partial output
    and
      alt timer fires
        Tool->>Exec: signal.abort (timer)
        Exec-->>Tool: partial output + abort/error
        Tool-->>Client: result { status: TIMEOUT, partialOutput }
      else user aborts
        Client->>Tool: user abort
        Tool->>Exec: signal.abort
        Exec-->>Tool: aborted
        Tool-->>Client: result { status: EXECUTION_FAILED, message: aborted }
      else completes
        Exec-->>Tool: success result
        Tool-->>Client: success result
      end
    end
  else unlimited
    Tool->>Exec: launch(..., signal: userSignal)
    Exec-->>Tool: success/abort result
    Tool-->>Client: result
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐇 I nibbled bytes and set the clocks,

defaults, max, and handy locks,
When timers chirp and tasks must cease,
I fetch the bits and give you peace,
A rabbit’s hop to keep things brisk.

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Linked Issues check ❓ Inconclusive The PR addresses core requirements from #920 (adding ephemeral settings, validation, documentation) but the raw summary shows the actual timeout implementation already exists in core packages; this PR only exposes the CLI surface. Clarify whether timeout parameter passing in shell and task tool invocations is complete; the PR description states core support exists but the acoliver comment suggests uncertainty about full coverage.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding CLI configuration for timeout settings on task and shell tools.
Description check ✅ Passed The description covers the overview, background, changes made with specific file locations, and closes the linked issue. However, it does not include the Testing Matrix or Reviewer Test Plan sections from the template.
Out of Scope Changes check ✅ Passed All changes (ephemeral settings, validation, tests, documentation) are directly related to exposing timeout CLI configuration as scoped in #920; no out-of-scope changes detected.
✨ Finishing touches
  • 📝 Generate docstrings

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 and usage tips.

@github-actions
Copy link
Contributor

github-actions bot commented Jan 6, 2026

LLxprt PR Review – PR #1021

Issue Alignment

Side Effects

  • Added timeout controllers managing dual AbortSignal handling (user + timeout). Potential memory leak risk if event listeners not properly removed, but implementation shows proper cleanup in try/finally blocks.
  • CLI validation prevents negative values except -1, but no explicit max bounds checking beyond ephemeral settings.

Code Quality

  • Error handling is robust with clear distinction between timeout vs user abort scenarios. Both tools use consistent timeout resolution logic.
  • Added proper signal cleanup and timeout management. TaskTool constructor now requires config parameter (minor API change handled internally).
  • CLI validation includes helpful error messages and checks for positive integers or -1.

Tests & Coverage

  • Coverage impact: increase – Added comprehensive timeout handling tests for both tools including default, max clamping, unlimited, timeout error, and user abort scenarios.
  • Tests avoid "mock theater" by testing actual timeout logic execution rather than just implementation details. Timeout tests use vi.useFakeTimers for deterministic behavior.

Verdict

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI Agents
In @packages/cli/src/ui/commands/setCommand.test.ts:
- Around line 176-213: The failing test leaves mock state from prior tests, so
before asserting mockRuntime.setEphemeralSetting was not called you must clear
the mock(s); update the "rejects invalid timeout settings" test (around the it
block calling setCommand.action) to call a mock reset such as
mockRuntime.setEphemeralSetting.mockClear() or jest.clearAllMocks() before the
for-loop (or at start of each iteration) so each invalid case begins with a
clean mock and the
expect(mockRuntime.setEphemeralSetting).not.toHaveBeenCalled() assertion is
reliable.

In @packages/core/src/tools/task.ts:
- Around line 221-228: The code treats -1 as a numeric timeout which causes
setTimeout(-1) and incorrect clamping; change the logic around timeoutMs,
this.params.timeout_ms, defaultTimeout and maxTimeout so that -1 means
"unlimited"/undefined: compute requestedTimeout = this.params.timeout_ms ??
defaultTimeout, then if requestedTimeout === -1 treat it as undefined; also
treat maxTimeout === -1 as "no limit" (i.e., skip Math.min). Finally set
timeoutMs to undefined when requestedTimeout is undefined, otherwise if
maxTimeout !== -1 use Math.min(requestedTimeout, maxTimeout) else use
requestedTimeout; remove the redundant DEFAULT_TASK_TIMEOUT_MS fallback since
defaultTimeout already defaults elsewhere to DEFAULT_TASK_TIMEOUT_MS to avoid
ever passing -1 to setTimeout.
🧹 Nitpick comments (2)
packages/core/src/tools/shell.ts (1)

261-276: Simplify redundant nullish coalescing and remove unnecessary type assertions.

Line 263-264: The type assertion as number | undefined is unnecessary since ephemeralSettings is already typed as EphemeralSettings which has these fields as number | undefined.

Line 274: The double nullish coalescing is redundant since defaultTimeout already has DEFAULT_SHELL_TIMEOUT_MS as its fallback.

🔎 Proposed simplification
     const ephemeralSettings = this.config.getEphemeralSettings();
     const defaultTimeout =
-      (ephemeralSettings.shell_default_timeout_ms as number | undefined) ??
+      ephemeralSettings.shell_default_timeout_ms ??
       DEFAULT_SHELL_TIMEOUT_MS;
     const maxTimeout =
-      (ephemeralSettings.shell_max_timeout_ms as number | undefined) ??
+      ephemeralSettings.shell_max_timeout_ms ??
       MAX_SHELL_TIMEOUT_MS;

     let timeoutMs: number | undefined;
     if (this.params.timeout_ms === -1) {
       timeoutMs = undefined;
     } else {
       const requestedTimeout =
-        this.params.timeout_ms ?? defaultTimeout ?? DEFAULT_SHELL_TIMEOUT_MS;
+        this.params.timeout_ms ?? defaultTimeout;
       timeoutMs = Math.min(requestedTimeout, maxTimeout);
     }
packages/cli/src/ui/commands/setCommand.test.ts (1)

135-155: Consider clearing mocks between loop iterations.

The test iterates over multiple cases but doesn't clear mocks between iterations. While the current assertions use toHaveBeenCalledWith which checks for any matching call, this could lead to false positives if a previous iteration's mock state affects later assertions.

🔎 Proposed fix
   it('validates task timeout settings', async () => {
     const testCases = [
       { key: 'task_default_timeout_ms', value: '90000' },
       { key: 'task_max_timeout_ms', value: '180000' },
       { key: 'shell_default_timeout_ms', value: '60000' },
       { key: 'shell_max_timeout_ms', value: '300000' },
     ];

     for (const { key, value } of testCases) {
+      vi.clearAllMocks();
       const result = await setCommand.action!(context, `${key} ${value}`);
       expect(mockRuntime.setEphemeralSetting).toHaveBeenCalledWith(
         key,
         Number(value),
       );
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ec58191 and fcf2154.

📒 Files selected for processing (8)
  • docs/settings-and-profiles.md
  • packages/cli/src/settings/ephemeralSettings.ts
  • packages/cli/src/ui/commands/setCommand.test.ts
  • packages/core/src/tools/shell.test.ts
  • packages/core/src/tools/shell.ts
  • packages/core/src/tools/task.test.ts
  • packages/core/src/tools/task.ts
  • packages/core/src/types/modelParams.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Don't use any - Always specify proper types. Use unknown if the type is truly unknown and add proper type guards.
Do not use console.log or console.debug - Use the sophisticated logging system instead. Log files are written to ~/.llxprt/debug/
Fix all linting errors, including warnings about any types

Files:

  • packages/core/src/types/modelParams.ts
  • packages/cli/src/settings/ephemeralSettings.ts
  • packages/cli/src/ui/commands/setCommand.test.ts
  • packages/core/src/tools/shell.test.ts
  • packages/core/src/tools/shell.ts
  • packages/core/src/tools/task.test.ts
  • packages/core/src/tools/task.ts
**/*.md

📄 CodeRabbit inference engine (CLAUDE.md)

Documentation-only changes (*.md files, docs/) do NOT require build/test/lint cycle

Files:

  • docs/settings-and-profiles.md
🧠 Learnings (6)
📚 Learning: 2026-01-03T00:20:08.040Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-01-03T00:20:08.040Z
Learning: Shell tool (packages/core/src/tools/shell.ts) always applies tool-output-max-tokens via limitOutputTokens to the model-facing llmContent at the end of execute(), formatting a warning when truncated.

Applied to files:

  • packages/core/src/types/modelParams.ts
  • packages/core/src/tools/shell.test.ts
  • packages/core/src/tools/shell.ts
📚 Learning: 2025-11-16T22:51:26.374Z
Learnt from: e2720pjk
Repo: vybestack/llxprt-code PR: 583
File: packages/core/src/providers/openai/OpenAIProvider.ts:935-959
Timestamp: 2025-11-16T22:51:26.374Z
Learning: In the llxprt-code codebase (packages/core/src/providers/openai/OpenAIProvider.ts), tools like `run_shell_command` use internal streaming only for real-time UI updates during execution, but each tool execution produces exactly ONE final `ToolResponseBlock` containing the full result. The streaming chunks are never sent to the LLM and are not converted into multiple tool messages. The OpenAI Chat Completions API requires that each tool call (tool_call_id) corresponds to exactly one message with role 'tool', so duplicate tool response detection that removes subsequent tool messages with the same tool_call_id is correct and necessary for API compliance.

Applied to files:

  • packages/core/src/tools/shell.test.ts
  • packages/core/src/tools/shell.ts
  • packages/core/src/tools/task.test.ts
📚 Learning: 2025-12-18T14:06:22.557Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2025-12-18T14:06:22.557Z
Learning: In the llxprt-code codebase, the `tool-output-max-items` ephemeral setting only applies to tools that return lists/collections (glob, grep, read-many-files), not to single-output tools like shell. Not all ephemerals are relevant to every tool.

Applied to files:

  • docs/settings-and-profiles.md
📚 Learning: 2026-01-03T00:20:08.040Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-01-03T00:20:08.040Z
Learning: ShellExecutionService applies a hard cap only in the child_process path (appendAndTruncate, “16MB” message) and currently has no truncation in the PTY path, which can lead to unbounded memory before tool-level token limiting runs.

Applied to files:

  • packages/core/src/tools/shell.ts
📚 Learning: 2025-12-05T14:59:34.368Z
Learnt from: CR
Repo: vybestack/llxprt-code PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-05T14:59:34.368Z
Learning: Use subagents (general-purpose, typescript-code-reviewer, or typescript-coder) for complex multi-step tasks, research, complex implementations, code review, and extensive file searching

Applied to files:

  • packages/core/src/tools/task.test.ts
  • packages/core/src/tools/task.ts
📚 Learning: 2025-12-05T14:59:34.368Z
Learnt from: CR
Repo: vybestack/llxprt-code PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-05T14:59:34.368Z
Learning: Run `npm run typecheck` to ensure type safety

Applied to files:

  • packages/core/src/tools/task.test.ts
🧬 Code graph analysis (4)
packages/cli/src/ui/commands/setCommand.test.ts (2)
packages/cli/src/ui/commands/setCommand.ts (1)
  • setCommand (595-806)
scripts/oldui-tmux-harness.js (1)
  • key (274-274)
packages/core/src/tools/shell.test.ts (1)
packages/core/src/services/shellExecutionService.ts (1)
  • ShellExecutionResult (32-50)
packages/core/src/tools/shell.ts (1)
packages/core/src/utils/toolOutputLimiter.ts (1)
  • formatLimitedOutput (232-257)
packages/core/src/tools/task.ts (4)
packages/core/src/tools/tools.ts (1)
  • ToolResult (423-451)
packages/core/src/core/subagentOrchestrator.ts (1)
  • SubagentLaunchRequest (55-61)
packages/core/src/core/subagent.ts (1)
  • OutputObject (89-104)
packages/core/src/core/turn.ts (1)
  • DEFAULT_AGENT_ID (39-39)
⏰ Context from checks skipped due to timeout of 270000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Test (macos-latest, 24.x)
  • GitHub Check: Test (windows-latest, 24.x)
  • GitHub Check: Test (ubuntu-latest, 24.x)
  • GitHub Check: Slow E2E - Win
  • GitHub Check: E2E Test (macOS)
  • GitHub Check: E2E Test (Linux) - sandbox:docker
  • GitHub Check: E2E Test (Linux) - sandbox:none
🔇 Additional comments (14)
packages/core/src/types/modelParams.ts (1)

120-127: LGTM!

The new timeout fields are correctly typed as optional numbers and follow the naming convention used by other load balancer settings in this interface (underscore_case for timeout-related settings).

packages/core/src/tools/shell.ts (3)

437-463: LGTM!

The timeout vs user-cancellation distinction logic is correct. The message construction properly differentiates between the two cases and includes partial output when available.


513-524: LGTM!

The error payload correctly distinguishes between TIMEOUT and EXECUTION_FAILED error types, using the same condition as the message construction. This ensures consistent behavior throughout the error handling flow.


733-737: LGTM!

The schema correctly documents the timeout_ms parameter with accurate default/max values and the -1 unlimited option.

docs/settings-and-profiles.md (2)

96-102: LGTM!

The CLI examples are clear and demonstrate practical usage of the new timeout settings.


48-51: LGTM!

The documentation clearly describes the new timeout settings with appropriate defaults that match the implementation in task.ts (task_default_timeout_ms: 60000, task_max_timeout_ms: 300000). The naming convention is consistent across documentation and code.

packages/core/src/tools/shell.test.ts (2)

279-331: LGTM!

The timeout test suite is comprehensive and well-structured. It correctly uses fake timers, properly sets up ephemeral settings via the mock config, and validates both the error type and message content. The abort signal handling pattern in the mock is correct.


450-489: LGTM!

The test correctly verifies that user-initiated aborts produce EXECUTION_FAILED error type (not TIMEOUT) and include "cancelled" in the message, properly distinguishing between the two abort scenarios.

packages/cli/src/settings/ephemeralSettings.ts (2)

93-102: LGTM!

The help text entries are clear, consistent with the other settings, and correctly document the defaults and the -1 unlimited option.


477-494: LGTM!

The validation logic correctly handles all cases:

  • Accepts positive integers and -1
  • Rejects zero, other negative numbers, decimals, and non-numeric values

The error message clearly explains the expected format.

packages/core/src/tools/task.test.ts (3)

212-298: LGTM!

The timeout test is comprehensive and well-structured. It correctly:

  • Uses fake timers for deterministic testing
  • Mocks the launch to respond to abort signals
  • Verifies the TIMEOUT error type, message content, and metadata including terminateReason and emittedVars

501-551: LGTM!

The user abort distinction test correctly verifies that:

  • User-initiated aborts produce EXECUTION_FAILED (not TIMEOUT)
  • The metadata includes cancelled: true

This ensures the TaskTool matches the ShellTool behavior for abort handling.


86-95: Test correctly validates the runConfig.max_time_minutes field in the launch request.

The implementation properly constructs maxTimeMinutes by converting timeout milliseconds to minutes (60,000 ms ÷ 60,000 = 1 minute), and the test assertion correctly verifies this field is passed through to the orchestrator.

packages/core/src/tools/task.ts (1)

119-120: Excellent timeout implementation with sophisticated abort coordination.

The timeout functionality is well-architected:

  • Configuration: Properly reads ephemeral settings (task_default_timeout_ms, task_max_timeout_ms) with sensible hardcoded fallbacks (60s default, 5min max).
  • AbortSignal coordination: Creates a separate timeoutController and elegantly links it with the user's signal, distinguishing timeout aborts from user-initiated aborts throughout execution (lines 287-291, 325-327, etc.).
  • Comprehensive coverage: Handles timeouts at multiple stages—during launch, post-launch, execution, subagent termination, and catch blocks—ensuring consistent behavior.
  • Cleanup: Properly clears timeout timers and removes event listeners in all code paths, including teardown and error branches.
  • Result construction: The new createTimeoutResult helper (lines 516-546) produces standardized ToolResult objects with TIMEOUT error type, partial output, and clear metadata.
  • Schema documentation: The timeout_ms parameter is well-documented for LLM consumption (lines 634-638).

The threading of maxTimeMinutes into runConfig.max_time_minutes (lines 145-147) correctly propagates the timeout constraint to the orchestrator and subagent layers.

Also applies to: 127-127, 139-139, 145-147, 230-250, 287-291, 304-306, 317-320, 325-361, 410-430, 451-465, 516-546, 565-565, 634-638, 666-666

Comment on lines +176 to +213
it('rejects invalid timeout settings', async () => {
const invalidCases = [
{
key: 'task_default_timeout_ms',
value: '-5',
expectedError:
'must be a positive integer in milliseconds or -1 for unlimited',
},
{
key: 'task_max_timeout_ms',
value: '0',
expectedError:
'must be a positive integer in milliseconds or -1 for unlimited',
},
{
key: 'shell_default_timeout_ms',
value: 'not-a-number',
expectedError:
'must be a positive integer in milliseconds or -1 for unlimited',
},
{
key: 'shell_max_timeout_ms',
value: '1.5',
expectedError:
'must be a positive integer in milliseconds or -1 for unlimited',
},
];

for (const { key, value, expectedError } of invalidCases) {
const result = await setCommand.action!(context, `${key} ${value}`);
expect(mockRuntime.setEphemeralSetting).not.toHaveBeenCalled();
expect(result).toEqual({
type: 'message',
messageType: 'error',
content: expect.stringContaining(expectedError),
});
}
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Reset mocks before invalid case assertions.

Since the previous test (validates task timeout settings) calls setEphemeralSetting successfully, the mock will have recorded those calls. The assertion expect(mockRuntime.setEphemeralSetting).not.toHaveBeenCalled() on line 206 will fail because the mock retains state from previous tests unless cleared.

This test should clear mocks before running or at the start of each iteration.

🔎 Proposed fix
   it('rejects invalid timeout settings', async () => {
     const invalidCases = [
       {
         key: 'task_default_timeout_ms',
         value: '-5',
         expectedError:
           'must be a positive integer in milliseconds or -1 for unlimited',
       },
       // ... other cases
     ];

     for (const { key, value, expectedError } of invalidCases) {
+      vi.clearAllMocks();
       const result = await setCommand.action!(context, `${key} ${value}`);
       expect(mockRuntime.setEphemeralSetting).not.toHaveBeenCalled();
🤖 Prompt for AI Agents
In @packages/cli/src/ui/commands/setCommand.test.ts around lines 176-213, The
failing test leaves mock state from prior tests, so before asserting
mockRuntime.setEphemeralSetting was not called you must clear the mock(s);
update the "rejects invalid timeout settings" test (around the it block calling
setCommand.action) to call a mock reset such as
mockRuntime.setEphemeralSetting.mockClear() or jest.clearAllMocks() before the
for-loop (or at start of each iteration) so each invalid case begins with a
clean mock and the
expect(mockRuntime.setEphemeralSetting).not.toHaveBeenCalled() assertion is
reliable.

…loses #920)

This commit adds CLI configuration support for tool-level timeouts as requested in issue #920.

Changes:
- Added 4 new ephemeral settings in ephemeralSettings.ts
- Added validation: accepts positive integers OR -1 for unlimited
- Added 3 new tests in setCommand.test.ts
- Updated setCommand.test.ts invalid-keys test to include new keys
- Updated docs/settings-and-profiles.md with documentation

Note: The core timeout implementation was already present in task.ts and shell.ts. This commit only adds the CLI settings surface for users to configure these values.

closes #920
@github-actions
Copy link
Contributor

github-actions bot commented Jan 6, 2026

Code Coverage Summary

Package Lines Statements Functions Branches
CLI 45.51% 45.51% 54.81% 75.36%
Core 71.06% 71.06% 73.65% 78.79%
CLI Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   45.51 |    75.36 |   54.81 |   45.51 |                   
 src               |   32.04 |    46.06 |      50 |   32.04 |                   
  gemini.tsx       |   14.52 |    57.14 |   28.57 |   14.52 | ...,332-1113,1121 
  ...ractiveCli.ts |   69.23 |    47.72 |   33.33 |   69.23 | ...50-251,284-292 
  ...liCommands.ts |   97.22 |       60 |     100 |   97.22 | 39-40             
  ...ActiveAuth.ts |      36 |    35.71 |      80 |      36 | ...64-169,186-195 
 src/auth          |   46.79 |    65.37 |   64.58 |   46.79 |                   
  ...andlerImpl.ts |   90.72 |    84.61 |   71.42 |   90.72 | ...48-149,155-159 
  ...henticator.ts |    92.3 |    95.23 |   66.66 |    92.3 | 80-88             
  ...ketManager.ts |     100 |      100 |     100 |     100 |                   
  ...h-provider.ts |   58.98 |    59.57 |   66.66 |   58.98 | ...84-518,526-549 
  ...h-provider.ts |   40.74 |    85.71 |   69.23 |   40.74 | ...72-485,489-531 
  ...h-provider.ts |   17.74 |       90 |   27.77 |   17.74 | ...31-562,568-587 
  ...l-oauth-ui.ts |   54.16 |      100 |      40 |   54.16 | 26-32,38-39,57-61 
  ...h-callback.ts |   82.94 |    75.67 |    90.9 |   82.94 | ...74-775,788-790 
  migration.ts     |       0 |        0 |       0 |       0 | 1-69              
  oauth-manager.ts |   42.02 |    53.79 |   70.83 |   42.02 | ...1560,1568-1769 
  ...h-provider.ts |   36.15 |    31.81 |      40 |   36.15 | ...52-490,498-534 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/commands      |   70.45 |      100 |      25 |   70.45 |                   
  extensions.tsx   |   55.55 |      100 |       0 |   55.55 | 21-31,35          
  mcp.ts           |   94.11 |      100 |      50 |   94.11 | 26                
 ...nds/extensions |   45.47 |    97.14 |   32.14 |   45.47 |                   
  disable.ts       |   17.54 |      100 |       0 |   17.54 | 17-30,36-63,65-69 
  enable.ts        |   16.12 |      100 |       0 |   16.12 | 17-36,42-68,70-74 
  install.ts       |   93.22 |    95.45 |   66.66 |   93.22 | 138,141-147       
  link.ts          |   26.31 |      100 |       0 |   26.31 | 20-37,44-49,51-54 
  list.ts          |   32.14 |      100 |       0 |   32.14 | 11-27,34-35       
  new.ts           |     100 |      100 |     100 |     100 |                   
  uninstall.ts     |   44.11 |      100 |   33.33 |   44.11 | 14-22,34-39,42-45 
  update.ts        |   10.94 |      100 |       0 |   10.94 | ...42-157,159-163 
 ...les/mcp-server |       0 |        0 |       0 |       0 |                   
  example.ts       |       0 |        0 |       0 |       0 | 1-60              
 src/commands/mcp  |   97.15 |    86.44 |    90.9 |   97.15 |                   
  add.ts           |     100 |    96.15 |     100 |     100 | 210               
  list.ts          |   90.65 |    80.76 |      80 |   90.65 | ...11-113,138-139 
  remove.ts        |     100 |    71.42 |     100 |     100 | 19-23             
 src/config        |   84.09 |     79.6 |   75.55 |   84.09 |                   
  auth.ts          |   90.69 |    89.47 |     100 |   90.69 | 19-20,57-58       
  ...alSettings.ts |   86.66 |    88.88 |     100 |   86.66 | 40-41,44-47       
  config.ts        |   78.37 |    81.78 |      76 |   78.37 | ...1765,1768-1772 
  extension.ts     |   80.06 |    89.26 |   78.78 |   80.06 | ...87-788,791-792 
  keyBindings.ts   |     100 |      100 |     100 |     100 |                   
  paths.ts         |     100 |      100 |     100 |     100 |                   
  ...eBootstrap.ts |      86 |     82.5 |      90 |      86 | ...51-753,762-763 
  sandboxConfig.ts |   66.66 |    47.77 |   89.47 |   66.66 | ...87-494,512-513 
  ...oxProfiles.ts |    8.53 |      100 |       0 |    8.53 | 47-48,51-129      
  settings.ts      |   86.59 |    75.73 |      72 |   86.59 | ...73-774,828-829 
  ...ingsSchema.ts |     100 |      100 |     100 |     100 |                   
  ...tedFolders.ts |   97.94 |    95.45 |     100 |   97.94 | 86,180-181        
  welcomeConfig.ts |   21.05 |      100 |       0 |   21.05 | ...70,73-78,81-82 
 ...fig/extensions |    63.6 |     87.5 |   83.78 |    63.6 |                   
  ...Enablement.ts |   95.37 |    95.52 |     100 |   95.37 | ...87-189,233-235 
  github.ts        |   44.11 |    86.79 |   54.54 |   44.11 | ...57-344,395-448 
  update.ts        |   62.33 |    46.15 |   66.66 |   62.33 | ...19-145,161-169 
  ...ableSchema.ts |     100 |      100 |     100 |     100 |                   
  variables.ts     |   95.34 |    89.47 |     100 |   95.34 | 30-31             
 src/constants     |     100 |      100 |     100 |     100 |                   
  historyLimits.ts |     100 |      100 |     100 |     100 |                   
 src/extensions    |   65.75 |    57.89 |      75 |   65.75 |                   
  ...utoUpdater.ts |   65.75 |    57.89 |      75 |   65.75 | ...49-450,459,461 
 src/generated     |     100 |      100 |     100 |     100 |                   
  git-commit.ts    |     100 |      100 |     100 |     100 |                   
 ...egration-tests |   90.72 |    84.61 |     100 |   90.72 |                   
  test-utils.ts    |   90.72 |    84.61 |     100 |   90.72 | ...01,219-220,230 
 src/patches       |       0 |        0 |       0 |       0 |                   
  is-in-ci.ts      |       0 |        0 |       0 |       0 | 1-17              
 src/providers     |   82.64 |    68.29 |   83.67 |   82.64 |                   
  IFileSystem.ts   |    86.2 |    85.71 |   85.71 |    86.2 | 51-52,67-68       
  ...Precedence.ts |   94.59 |    86.66 |     100 |   94.59 | 40-41             
  index.ts         |       0 |        0 |       0 |       0 | 1-19              
  ...gistration.ts |   77.94 |    68.75 |   33.33 |   77.94 | ...,93-97,103-104 
  ...derAliases.ts |   74.35 |    70.37 |     100 |   74.35 | ...27-133,138-139 
  ...onfigUtils.ts |   92.45 |       75 |     100 |   92.45 | 25-29             
  ...erInstance.ts |   83.64 |    64.75 |   88.46 |   83.64 | ...49-753,770-774 
  types.ts         |       0 |        0 |       0 |       0 | 1-8               
 ...viders/logging |   87.59 |    88.63 |   63.63 |   87.59 |                   
  ...rvice-impl.ts |   44.44 |        0 |       0 |   44.44 | 21-22,25-30,36-37 
  git-stats.ts     |   94.59 |    90.69 |     100 |   94.59 | ...48-149,180-181 
 src/runtime       |   67.09 |    72.04 |   70.24 |   67.09 |                   
  ...imeAdapter.ts |   97.03 |    89.65 |     100 |   97.03 | ...38,344-345,541 
  ...etFailover.ts |   98.93 |    93.54 |     100 |   98.93 | 205               
  messages.ts      |      20 |      100 |       0 |      20 | ...0,38-66,74-102 
  ...pplication.ts |   82.64 |    71.31 |      70 |   82.64 | ...59-662,673-674 
  ...extFactory.ts |   91.28 |    72.41 |     100 |   91.28 | ...63-266,351-358 
  ...meSettings.ts |   55.44 |    66.55 |   56.06 |   55.44 | ...2169,2194-2248 
 src/services      |   71.55 |    87.34 |   82.35 |   71.55 |                   
  ...mandLoader.ts |     100 |      100 |     100 |     100 |                   
  ...ardService.ts |    91.3 |    33.33 |     100 |    91.3 | 35-36             
  ...andService.ts |     100 |      100 |     100 |     100 |                   
  ...mandLoader.ts |   88.77 |    90.47 |     100 |   88.77 | ...79-184,258-265 
  ...omptLoader.ts |   30.68 |    81.25 |      50 |   30.68 | ...80-281,284-288 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...mpt-processors |   97.56 |    94.11 |     100 |   97.56 |                   
  ...tProcessor.ts |     100 |      100 |     100 |     100 |                   
  ...lProcessor.ts |   97.36 |    93.61 |     100 |   97.36 | 77-78,202-203     
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...o-continuation |   86.01 |     78.4 |   94.11 |   86.01 |                   
  ...ionService.ts |   86.01 |     78.4 |   94.11 |   86.01 | ...94,562,588-589 
 src/settings      |   62.29 |    78.07 |     100 |   62.29 |                   
  ...alSettings.ts |   61.87 |    79.43 |     100 |   61.87 | ...26-437,440-446 
  ...aramParser.ts |   71.42 |    57.14 |     100 |   71.42 | 21-22,24-25,30-31 
 src/test-utils    |   57.56 |    78.57 |   42.85 |   57.56 |                   
  ...eExtension.ts |     100 |      100 |     100 |     100 |                   
  ...omMatchers.ts |   21.21 |      100 |       0 |   21.21 | 22-50             
  ...andContext.ts |     100 |      100 |     100 |     100 |                   
  render.tsx       |       0 |        0 |       0 |       0 | 1-37              
  ...e-testing.tsx |       0 |        0 |       0 |       0 | 1-54              
  ...iderConfig.ts |       0 |        0 |       0 |       0 | 1-19              
 src/ui            |   16.41 |    98.38 |   34.78 |   16.41 |                   
  App.tsx          |   33.89 |      100 |       0 |   33.89 | 50-86,92-99       
  AppContainer.tsx |    5.38 |      100 |       0 |    5.38 | 144-153,182-2292  
  ...tionNudge.tsx |    6.75 |      100 |       0 |    6.75 | 26-101            
  colors.ts        |   40.67 |      100 |   28.57 |   40.67 | ...86-287,291-292 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...derOptions.ts |     100 |      100 |     100 |     100 |                   
  keyMatchers.ts   |   95.65 |    96.29 |     100 |   95.65 | 29-30             
  ...ntsEnabled.ts |     100 |      100 |     100 |     100 |                   
  ...submission.ts |     100 |      100 |     100 |     100 |                   
  ...tic-colors.ts |     100 |      100 |     100 |     100 |                   
  textConstants.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/ui/commands   |   65.72 |    75.32 |   63.95 |   65.72 |                   
  aboutCommand.ts  |   74.81 |       24 |     100 |   74.81 | ...05,112-113,140 
  authCommand.ts   |   74.95 |     84.4 |   83.33 |   74.95 | ...39-642,652-676 
  ...urlCommand.ts |      30 |      100 |       0 |      30 | 20-40             
  bugCommand.ts    |   79.16 |     37.5 |     100 |   79.16 | 32-35,42,79-88    
  chatCommand.ts   |   63.38 |    77.27 |      50 |   63.38 | ...87-509,526-536 
  clearCommand.ts  |     100 |      100 |     100 |     100 |                   
  ...essCommand.ts |     100 |    88.88 |     100 |     100 | 71                
  copyCommand.ts   |   98.27 |    94.44 |     100 |   98.27 | 37                
  debugCommands.ts |   13.29 |      100 |       0 |   13.29 | ...48,455,462,469 
  ...icsCommand.ts |    62.5 |    57.14 |   33.33 |    62.5 | ...88,320,427-432 
  ...ryCommand.tsx |   16.86 |      100 |       0 |   16.86 | ...38-148,155-179 
  docsCommand.ts   |     100 |      100 |     100 |     100 |                   
  ...extCommand.ts |   93.18 |    77.77 |     100 |   93.18 | 108-113           
  editorCommand.ts |     100 |      100 |     100 |     100 |                   
  ...onsCommand.ts |   91.86 |    88.88 |     100 |   91.86 | 86-94,96          
  helpCommand.ts   |     100 |      100 |     100 |     100 |                   
  ideCommand.ts    |   66.35 |    68.96 |   55.55 |   66.35 | ...22-225,233-240 
  initCommand.ts   |   83.33 |    71.42 |   66.66 |   83.33 | 35-39,41-85       
  keyCommand.ts    |     100 |    77.77 |     100 |     100 | 47                
  ...ileCommand.ts |   11.11 |      100 |       0 |   11.11 | 23-134            
  ...ingCommand.ts |   10.96 |      100 |       0 |   10.96 | ...59-528,545-556 
  logoutCommand.ts |   15.62 |      100 |       0 |   15.62 | 21-85             
  mcpCommand.ts    |   82.35 |    82.22 |   83.33 |   82.35 | ...09-410,428-429 
  memoryCommand.ts |   88.82 |    83.87 |     100 |   88.82 | 69-83,96-101,152  
  modelCommand.ts  |   25.71 |      100 |       0 |   25.71 | 21-51             
  mouseCommand.ts  |     100 |      100 |     100 |     100 |                   
  ...onsCommand.ts |     100 |      100 |     100 |     100 |                   
  ...iesCommand.ts |   97.02 |    82.85 |     100 |   97.02 | 27,40-41          
  ...acyCommand.ts |   61.53 |      100 |       0 |   61.53 | 22-26             
  ...ileCommand.ts |   65.08 |    72.03 |      90 |   65.08 | ...08-913,932-945 
  ...derCommand.ts |   53.12 |    30.55 |      80 |   53.12 | ...58-262,270-275 
  quitCommand.ts   |   34.48 |      100 |       0 |   34.48 | 16-35             
  ...oreCommand.ts |   92.53 |     87.5 |     100 |   92.53 | ...,90-91,120-125 
  setCommand.ts    |   81.68 |    77.27 |      80 |   81.68 | ...77-782,824-837 
  ...ngsCommand.ts |     100 |      100 |     100 |     100 |                   
  ...hubCommand.ts |     100 |      100 |     100 |     100 |                   
  statsCommand.ts  |   94.33 |     90.9 |     100 |   94.33 | 26-34             
  statusCommand.ts |   13.63 |      100 |       0 |   13.63 | 20-87             
  ...entCommand.ts |   79.57 |    72.04 |   83.33 |   79.57 | ...67-880,883-896 
  ...tupCommand.ts |     100 |      100 |     100 |     100 |                   
  themeCommand.ts  |     100 |      100 |     100 |     100 |                   
  ...matCommand.ts |   26.66 |      100 |       0 |   26.66 | 33-92             
  toolsCommand.ts  |   84.98 |     74.6 |     100 |   84.98 | ...85-294,307-308 
  types.ts         |     100 |      100 |     100 |     100 |                   
  ...ileCommand.ts |   61.11 |      100 |       0 |   61.11 | 16-22             
  vimCommand.ts    |   44.44 |      100 |       0 |   44.44 | 14-24             
 ...ommands/schema |   96.22 |    91.02 |    92.3 |   96.22 |                   
  index.ts         |   96.45 |    91.61 |     100 |   96.45 | ...08-412,423-424 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 src/ui/components |   10.81 |    35.95 |     2.5 |   10.81 |                   
  AboutBox.tsx     |    4.06 |      100 |       0 |    4.06 | 27-160            
  AsciiArt.ts      |     100 |      100 |     100 |     100 |                   
  AuthDialog.tsx   |    6.47 |      100 |       0 |    6.47 | 27-187            
  ...nProgress.tsx |   16.66 |      100 |       0 |   16.66 | 18-62             
  ...Indicator.tsx |   15.15 |      100 |       0 |   15.15 | 17-47             
  ...firmation.tsx |    7.43 |      100 |       0 |    7.43 | 45-177            
  ...tsDisplay.tsx |    7.69 |      100 |       0 |    7.69 | 23-34,38-156      
  CliSpinner.tsx   |   38.46 |      100 |       0 |   38.46 | 16-24             
  Composer.tsx     |   10.86 |      100 |       0 |   10.86 | 24-68             
  ...entPrompt.tsx |   18.75 |      100 |       0 |   18.75 | 21-51             
  ...ryDisplay.tsx |   21.05 |      100 |       0 |   21.05 | 17-35             
  ...ryDisplay.tsx |    4.93 |      100 |       0 |    4.93 | 26-112            
  ...geDisplay.tsx |       0 |        0 |       0 |       0 | 1-37              
  ...gProfiler.tsx |   17.88 |      100 |       0 |   17.88 | ...71-116,120-199 
  ...esDisplay.tsx |   10.52 |      100 |       0 |   10.52 | 24-82             
  ...ogManager.tsx |   11.76 |      100 |       0 |   11.76 | 48-314            
  ...ngsDialog.tsx |    6.53 |      100 |       0 |    6.53 | 27-189            
  ...rBoundary.tsx |    9.48 |        0 |       0 |    9.48 | ...15-158,176-188 
  ...ustDialog.tsx |    15.9 |      100 |       0 |    15.9 | 31-121            
  Footer.tsx       |    8.94 |      100 |     100 |    8.94 | ...30-508,512-525 
  ...ngSpinner.tsx |   38.09 |      100 |       0 |   38.09 | 30-46             
  Header.tsx       |    17.5 |      100 |       0 |    17.5 | 22-62             
  Help.tsx         |    3.17 |      100 |       0 |    3.17 | 17-179            
  ...emDisplay.tsx |   18.32 |      100 |       0 |   18.32 | 50-180            
  InputPrompt.tsx  |   37.68 |    37.34 |   66.66 |   37.68 | ...5-883,897-1040 
  ...tsDisplay.tsx |    4.41 |      100 |       0 |    4.41 | 26-37,41-249      
  ...utManager.tsx |       0 |        0 |       0 |       0 | 1-97              
  ...ileDialog.tsx |    6.89 |      100 |       0 |    6.89 | 20-119            
  ...Indicator.tsx |   14.54 |      100 |       0 |   14.54 | 24-81             
  ...ingDialog.tsx |    4.52 |      100 |       0 |    4.52 | ...9,84-90,93-354 
  ...geDisplay.tsx |       0 |        0 |       0 |       0 | 1-40              
  ...tsDisplay.tsx |    6.28 |      100 |       0 |    6.28 | 33-52,56-214      
  ...fications.tsx |   12.98 |      100 |       0 |   12.98 | 27-104            
  ...odeDialog.tsx |    7.31 |      100 |       0 |    7.31 | 30-140            
  ...ustDialog.tsx |    5.88 |      100 |       0 |    5.88 | 29-228            
  PrepareLabel.tsx |   13.33 |      100 |       0 |   13.33 | 20-48             
  ...derDialog.tsx |    3.84 |      100 |       0 |    3.84 | 22-272            
  ...delDialog.tsx |    2.99 |      100 |       0 |    2.99 | 23-361            
  ...eKeyInput.tsx |       0 |        0 |       0 |       0 | 1-98              
  ...ryDisplay.tsx |      50 |      100 |       0 |      50 | 15-17             
  ...ngsDialog.tsx |    1.87 |      100 |       0 |    1.87 | ...9-108,111-1258 
  ...ionDialog.tsx |   14.28 |      100 |       0 |   14.28 | 35-121            
  ...Indicator.tsx |   44.44 |      100 |       0 |   44.44 | 12-17             
  ...MoreLines.tsx |      28 |      100 |       0 |      28 | 18-40             
  StatsDisplay.tsx |     6.5 |      100 |       0 |     6.5 | ...84-159,167-336 
  ...nsDisplay.tsx |    7.76 |      100 |       0 |    7.76 | 49-164            
  ThemeDialog.tsx  |       5 |      100 |       0 |       5 | 34-328            
  Tips.tsx         |      16 |      100 |       0 |      16 | 17-45             
  TodoPanel.tsx    |    4.48 |      100 |       0 |    4.48 | ...20-345,348-511 
  ...tsDisplay.tsx |    7.51 |      100 |       0 |    7.51 | 30-53,56-225      
  ToolsDialog.tsx  |    8.23 |      100 |       0 |    8.23 | 23-115            
  ...ification.tsx |   36.36 |      100 |       0 |   36.36 | 15-22             
  ...ionDialog.tsx |    8.13 |      100 |       0 |    8.13 | 18-114            
  todo-utils.ts    |     100 |      100 |     100 |     100 |                   
 ...comeOnboarding |   10.74 |        0 |       0 |   10.74 |                   
  ...ethodStep.tsx |   17.28 |      100 |       0 |   17.28 | 37-120            
  ...ationStep.tsx |     5.6 |      100 |       0 |     5.6 | 28-174            
  ...etionStep.tsx |    5.12 |      100 |       0 |    5.12 | 22-162            
  ...electStep.tsx |    8.13 |      100 |       0 |    8.13 | 30-129            
  ...electStep.tsx |    23.8 |      100 |       0 |    23.8 | 33-90             
  SkipExitStep.tsx |   12.82 |      100 |       0 |   12.82 | 18-57             
  ...omeDialog.tsx |   12.38 |      100 |       0 |   12.38 | 37-146            
  WelcomeStep.tsx  |   10.86 |      100 |       0 |   10.86 | 23-70             
  index.ts         |       0 |        0 |       0 |       0 | 1-13              
 ...nents/messages |   13.12 |    85.71 |    7.14 |   13.12 |                   
  ...onMessage.tsx |   13.72 |      100 |       0 |   13.72 | 24-80             
  DiffRenderer.tsx |    3.33 |      100 |       0 |    3.33 | ...79-360,363-381 
  ErrorMessage.tsx |   22.22 |      100 |       0 |   22.22 | 16-31             
  ...niMessage.tsx |   14.54 |      100 |       0 |   14.54 | 26-82             
  ...geContent.tsx |   19.04 |      100 |       0 |   19.04 | 25-43             
  InfoMessage.tsx  |   26.31 |      100 |       0 |   26.31 | 17-32             
  ...rlMessage.tsx |     100 |       50 |     100 |     100 | 26                
  ...ckDisplay.tsx |      20 |      100 |       0 |      20 | 43-64             
  ...onMessage.tsx |    3.87 |      100 |       0 |    3.87 | 43-507            
  ...upMessage.tsx |   10.36 |      100 |       0 |   10.36 | ...2,65-80,84-254 
  ToolMessage.tsx  |    8.36 |      100 |       0 |    8.36 | ...95-328,331-334 
  UserMessage.tsx  |     100 |      100 |     100 |     100 |                   
  ...llMessage.tsx |   36.36 |      100 |       0 |   36.36 | 17-25             
  ...ngMessage.tsx |   26.31 |      100 |       0 |   26.31 | 17-32             
 ...ponents/shared |   17.12 |     18.6 |   15.38 |   17.12 |                   
  ...ctionList.tsx |    5.55 |      100 |       0 |    5.55 | 53-184            
  MaxSizedBox.tsx  |    2.37 |      100 |       0 |    2.37 | 23-50,99-625      
  ...tonSelect.tsx |   13.63 |      100 |       0 |   13.63 | 57-100            
  ...lableList.tsx |    7.61 |      100 |       0 |    7.61 | 44-152            
  ...lizedList.tsx |    2.04 |      100 |       0 |    2.04 | 55-485            
  text-buffer.ts   |   33.26 |     18.6 |   22.22 |   33.26 | ...1903-1906,1911 
  ...er-actions.ts |    0.78 |      100 |       0 |    0.78 | 26-39,78-814      
 ...mponents/views |    12.9 |      100 |       0 |    12.9 |                   
  ChatList.tsx     |    12.9 |      100 |       0 |    12.9 | 17-46             
 src/ui/constants  |   89.28 |      100 |       0 |   89.28 |                   
  ...ollections.ts |   89.28 |      100 |       0 |   89.28 | 224-245           
 src/ui/containers |       0 |        0 |       0 |       0 |                   
  ...ontroller.tsx |       0 |        0 |       0 |       0 | 1-341             
  UIStateShell.tsx |       0 |        0 |       0 |       0 | 1-15              
 src/ui/contexts   |   59.93 |    74.39 |      50 |   59.93 |                   
  ...chContext.tsx |    64.7 |      100 |      50 |    64.7 | 24-29             
  FocusContext.tsx |       0 |        0 |       0 |       0 | 1-11              
  ...ssContext.tsx |   83.02 |    79.02 |      92 |   83.02 | ...1231,1263-1266 
  MouseContext.tsx |   78.88 |    66.66 |     100 |   78.88 | ...98-102,108-118 
  ...erContext.tsx |       0 |        0 |       0 |       0 | 1-120             
  ...owContext.tsx |   19.64 |      100 |       0 |   19.64 | 33,36,39-87       
  ...meContext.tsx |   46.51 |       25 |   28.57 |   46.51 | ...89,193-194,199 
  ...lProvider.tsx |   89.16 |    69.81 |     100 |   89.16 | ...79-380,387-388 
  ...onContext.tsx |    6.73 |      100 |       0 |    6.73 | ...88-282,287-294 
  ...teContext.tsx |       0 |        0 |       0 |       0 | 1-61              
  ...gsContext.tsx |      50 |      100 |       0 |      50 | 15-20             
  ...ngContext.tsx |   42.85 |      100 |       0 |   42.85 | 15-22             
  TodoContext.tsx  |   55.55 |      100 |       0 |   55.55 | 19-22,24-27       
  TodoProvider.tsx |    6.94 |      100 |       0 |    6.94 | 24-105            
  ...llContext.tsx |     100 |      100 |       0 |     100 |                   
  ...lProvider.tsx |    6.75 |      100 |       0 |    6.75 | 28-122            
  ...nsContext.tsx |      25 |      100 |       0 |      25 | 157-168,171-176   
  ...teContext.tsx |   27.77 |      100 |       0 |   27.77 | 189-198,201-206   
  ...deContext.tsx |   11.11 |      100 |       0 |   11.11 | 29-81,84-89       
 src/ui/editors    |   94.11 |    85.71 |   66.66 |   94.11 |                   
  ...ngsManager.ts |   94.11 |    85.71 |   66.66 |   94.11 | 55,69-70          
 src/ui/hooks      |   19.17 |    43.04 |      17 |   19.17 |                   
  ...dProcessor.ts |    2.53 |        0 |       0 |    2.53 | 31,60-515         
  index.ts         |       0 |        0 |       0 |       0 | 1-10              
  ...dProcessor.ts |    13.2 |      100 |      50 |    13.2 | 33-61,79-308      
  ...dProcessor.ts |    2.67 |      100 |       0 |    2.67 | 73-714            
  ...Completion.ts |   22.22 |      100 |      50 |   22.22 | ...34-157,162-242 
  ...uthCommand.ts |    6.45 |      100 |       0 |    6.45 | 15-135            
  ...tIndicator.ts |    12.5 |      100 |       0 |    12.5 | 19-66             
  ...chedScroll.ts |   16.66 |      100 |       0 |   16.66 | 14-32             
  ...ketedPaste.ts |      20 |      100 |       0 |      20 | 20-38             
  ...ompletion.tsx |   53.04 |    27.27 |     100 |   53.04 | ...06-245,258-274 
  useCompletion.ts |   45.56 |      100 |     100 |   45.56 | ...8,52-77,81-107 
  ...leMessages.ts |       5 |      100 |       0 |       5 | 29-65,68-118      
  ...orSettings.ts |   11.11 |      100 |       0 |   11.11 | 29-81             
  ...AutoUpdate.ts |    9.52 |      100 |       0 |    9.52 | 18-58             
  ...ionUpdates.ts |    4.36 |      100 |       0 |    4.36 | 36-48,51-244      
  ...erDetector.ts |   22.72 |      100 |       0 |   22.72 | 27-43             
  useFocus.ts      |    25.8 |      100 |       0 |    25.8 | 19-48             
  ...olderTrust.ts |   10.46 |      100 |       0 |   10.46 | 24-112            
  ...miniStream.ts |   49.83 |    45.66 |      40 |   49.83 | ...1369,1394-1496 
  ...BranchName.ts |   11.66 |      100 |       0 |   11.66 | 14-79             
  ...oryManager.ts |    5.22 |      100 |       0 |    5.22 | 53-212            
  ...stListener.ts |   12.12 |      100 |       0 |   12.12 | 17-50             
  ...putHistory.ts |    3.75 |      100 |       0 |    3.75 | 24-111            
  ...storyStore.ts |    4.61 |      100 |       0 |    4.61 | 24-112            
  useKeypress.ts   |   21.05 |      100 |       0 |   21.05 | 24-41             
  ...rdProtocol.ts |   36.36 |      100 |       0 |   36.36 | 24-31             
  ...fileDialog.ts |    5.71 |      100 |       0 |    5.71 | 27-135            
  ...gIndicator.ts |   12.24 |      100 |       0 |   12.24 | 14-64             
  useLogger.ts     |   93.75 |      100 |     100 |   93.75 | 26                
  ...oryMonitor.ts |      25 |      100 |       0 |      25 | 19-41             
  useMouse.ts      |   77.77 |    66.66 |     100 |   77.77 | 22-25             
  ...eSelection.ts |    3.13 |      100 |       0 |    3.13 | 36-103,106-315    
  ...oviderInfo.ts |       0 |        0 |       0 |       0 | 1-80              
  ...odifyTrust.ts |    9.09 |      100 |       0 |    9.09 | 46-137            
  ...raseCycler.ts |    9.43 |      100 |       0 |    9.43 | 24-80             
  ...cySettings.ts |    3.38 |      100 |       0 |    3.38 | 17-26,36-156      
  ...Completion.ts |   29.41 |       40 |     100 |   29.41 | ...14-227,236-242 
  ...iderDialog.ts |    7.89 |      100 |       0 |    7.89 | 27-110            
  ...odelDialog.ts |    9.37 |      100 |       0 |    9.37 | 25-86             
  ...lScheduler.ts |   21.22 |    29.41 |   66.66 |   21.22 | ...74-479,481-491 
  ...oryCommand.ts |       0 |        0 |       0 |       0 | 1-7               
  useResponsive.ts |   28.57 |      100 |       0 |   28.57 | 23-33             
  ...ompletion.tsx |   69.56 |      100 |     100 |   69.56 | 45-47,51-66,78-81 
  ...ectionList.ts |    2.94 |      100 |       0 |    2.94 | ...01-229,243-448 
  useSession.ts    |       0 |        0 |       0 |       0 | 1-23              
  ...ngsCommand.ts |   18.75 |      100 |       0 |   18.75 | 10-25             
  ...ellHistory.ts |    6.48 |      100 |       0 |    6.48 | 22-70,73-138      
  ...oryCommand.ts |       0 |        0 |       0 |       0 | 1-62              
  ...ompletion.tsx |   32.05 |    31.57 |      25 |   32.05 | ...89-797,822-860 
  ...leCallback.ts |       0 |        0 |       0 |       0 | 1-70              
  ...tateAndRef.ts |   59.09 |      100 |     100 |   59.09 | 23-31             
  ...oryRefresh.ts |   10.34 |      100 |       0 |   10.34 | 17-48             
  ...rminalSize.ts |   11.42 |      100 |       0 |   11.42 | 13-55             
  ...emeCommand.ts |    6.03 |      100 |       0 |    6.03 | 26-151            
  useTimer.ts      |    7.14 |      100 |       0 |    7.14 | 16-65             
  ...ntinuation.ts |       0 |        0 |       0 |       0 | 1-270             
  ...ePreserver.ts |   48.48 |      100 |      75 |   48.48 | 33-50             
  ...oolsDialog.ts |    4.67 |      100 |       0 |    4.67 | 24-145            
  ...Onboarding.ts |    2.96 |      100 |       0 |    2.96 | 76-348            
  ...eMigration.ts |   10.34 |      100 |       0 |   10.34 | 14-72             
  vim.ts           |    6.13 |      100 |       0 |    6.13 | ...76-111,129-784 
 src/ui/layouts    |    5.43 |      100 |       0 |    5.43 |                   
  ...AppLayout.tsx |    5.43 |      100 |       0 |    5.43 | 57-74,77-630      
 ...noninteractive |      75 |      100 |    6.66 |      75 |                   
  ...eractiveUi.ts |      75 |      100 |    6.66 |      75 | 17-19,23-24,27-28 
 src/ui/privacy    |   26.08 |      100 |       0 |   26.08 |                   
  ...acyNotice.tsx |   10.97 |      100 |       0 |   10.97 | 22-123            
  ...acyNotice.tsx |   14.28 |      100 |       0 |   14.28 | 16-59             
  ...acyNotice.tsx |   12.19 |      100 |       0 |   12.19 | 16-62             
  ...acyNotice.tsx |   42.46 |      100 |       0 |   42.46 | 78-91,99-186      
  ...acyNotice.tsx |   21.95 |      100 |       0 |   21.95 | 20-59,62-64       
 src/ui/reducers   |   77.87 |     90.9 |      50 |   77.87 |                   
  appReducer.ts    |     100 |      100 |     100 |     100 |                   
  ...ionReducer.ts |       0 |        0 |       0 |       0 | 1-52              
 src/ui/state      |   21.51 |      100 |       0 |   21.51 |                   
  extensions.ts    |   21.51 |      100 |       0 |   21.51 | 68-130            
 src/ui/themes     |   99.13 |    89.38 |      96 |   99.13 |                   
  ansi-light.ts    |     100 |      100 |     100 |     100 |                   
  ansi.ts          |     100 |      100 |     100 |     100 |                   
  atom-one-dark.ts |     100 |      100 |     100 |     100 |                   
  ayu-light.ts     |     100 |      100 |     100 |     100 |                   
  ayu.ts           |     100 |      100 |     100 |     100 |                   
  color-utils.ts   |     100 |      100 |     100 |     100 |                   
  default-light.ts |     100 |      100 |     100 |     100 |                   
  default.ts       |     100 |      100 |     100 |     100 |                   
  dracula.ts       |     100 |      100 |     100 |     100 |                   
  github-dark.ts   |     100 |      100 |     100 |     100 |                   
  github-light.ts  |     100 |      100 |     100 |     100 |                   
  googlecode.ts    |     100 |      100 |     100 |     100 |                   
  green-screen.ts  |     100 |      100 |     100 |     100 |                   
  no-color.ts      |     100 |      100 |     100 |     100 |                   
  ...c-resolver.ts |     100 |      100 |     100 |     100 |                   
  ...tic-tokens.ts |     100 |      100 |     100 |     100 |                   
  ...-of-purple.ts |     100 |      100 |     100 |     100 |                   
  theme-compat.ts  |     100 |       50 |     100 |     100 | 79                
  theme-manager.ts |   89.74 |    82.53 |     100 |   89.74 | ...04-310,315-316 
  theme.ts         |   99.41 |      100 |   85.71 |   99.41 | 185-186           
  xcode.ts         |     100 |      100 |     100 |     100 |                   
 src/ui/utils      |   44.08 |    86.39 |   63.11 |   44.08 |                   
  ...Colorizer.tsx |    5.88 |      100 |       0 |    5.88 | ...16-128,140-229 
  ...olePatcher.ts |      78 |    77.77 |     100 |      78 | 58-69             
  ...nRenderer.tsx |      10 |      100 |       0 |      10 | 26-155,164-173    
  ...wnDisplay.tsx |    6.02 |      100 |       0 |    6.02 | ...73-397,408-412 
  ...eRenderer.tsx |   10.63 |      100 |       0 |   10.63 | ...32-247,260-395 
  ...ketedPaste.ts |   55.55 |      100 |       0 |   55.55 | 11-12,15-16       
  clipboard.ts     |   97.29 |    84.61 |     100 |   97.29 | 40                
  ...boardUtils.ts |   32.25 |     37.5 |     100 |   32.25 | ...55-114,129-145 
  commandUtils.ts  |   92.79 |    88.63 |     100 |   92.79 | ...11,115,117-118 
  computeStats.ts  |     100 |      100 |     100 |     100 |                   
  displayUtils.ts  |     100 |      100 |     100 |     100 |                   
  formatters.ts    |   90.47 |       95 |     100 |   90.47 | 57-60             
  fuzzyFilter.ts   |     100 |    96.42 |     100 |     100 | 75                
  highlight.ts     |   65.43 |      100 |   66.66 |   65.43 | 77-110            
  input.ts         |     100 |    85.71 |     100 |     100 | 18                
  ...olDetector.ts |   12.34 |       50 |   16.66 |   12.34 | ...10-111,114-115 
  ...nUtilities.ts |   69.84 |    85.71 |     100 |   69.84 | 75-91,100-101     
  mouse.ts         |   85.16 |    73.68 |     100 |   85.16 | ...18-219,223-224 
  ...mConstants.ts |     100 |      100 |     100 |     100 |                   
  ...opDetector.ts |       0 |        0 |       0 |       0 | 1-209             
  responsive.ts    |    69.9 |    73.33 |      80 |    69.9 | ...95-103,106-121 
  ...putHandler.ts |   87.36 |    90.32 |     100 |   87.36 | 52-53,74-83       
  ...alContract.ts |     100 |      100 |     100 |     100 |                   
  terminalLinks.ts |     100 |      100 |     100 |     100 |                   
  ...lSequences.ts |     100 |      100 |     100 |     100 |                   
  terminalSetup.ts |    4.03 |      100 |       0 |    4.03 | 40-340            
  textUtils.ts     |   74.77 |    94.59 |   72.72 |   74.77 | ...14-115,135-137 
  ...Formatters.ts |   17.39 |      100 |       0 |   17.39 | 14-21,29-36,50-52 
  ...icsTracker.ts |     100 |    66.66 |     100 |     100 | 32-34             
  ui-sizing.ts     |   21.05 |      100 |       0 |   21.05 | 11-23,26-31       
  updateCheck.ts   |     100 |    93.33 |     100 |     100 | 27,38             
 src/utils         |   52.65 |    89.69 |   85.43 |   52.65 |                   
  ...ionContext.ts |   79.59 |       75 |     100 |   79.59 | 37-40,62-63,78-81 
  bootstrap.ts     |   94.11 |    88.88 |     100 |   94.11 | 71-72             
  checks.ts        |   33.33 |      100 |       0 |   33.33 | 23-28             
  cleanup.ts       |   72.72 |      100 |      75 |   72.72 | 43-52             
  commands.ts      |    50.9 |    63.63 |     100 |    50.9 | 25-26,45,57-84    
  commentJson.ts   |   92.17 |     92.5 |     100 |   92.17 | 92-100            
  ...ScopeUtils.ts |   19.23 |      100 |       0 |   19.23 | 23-40,46-73       
  ...icSettings.ts |   88.61 |    88.88 |     100 |   88.61 | ...37,40-43,61-64 
  ...arResolver.ts |   96.42 |       96 |     100 |   96.42 | 111-112           
  errors.ts        |   94.59 |       88 |     100 |   94.59 | 49-50,88-89       
  events.ts        |     100 |      100 |     100 |     100 |                   
  gitUtils.ts      |    92.5 |    82.35 |     100 |    92.5 | 61-62,77-80       
  ...AutoUpdate.ts |   52.71 |    95.23 |      50 |   52.71 | 88-153            
  ...lationInfo.ts |     100 |      100 |     100 |     100 |                   
  math.ts          |   66.66 |      100 |       0 |   66.66 | 15                
  package.ts       |   88.88 |    83.33 |     100 |   88.88 | 33-34             
  readStdin.ts     |   79.24 |       90 |      80 |   79.24 | 31-38,50-52       
  relaunch.ts      |     100 |      100 |     100 |     100 |                   
  resolvePath.ts   |   66.66 |       25 |     100 |   66.66 | 12-13,16,18-19    
  sandbox.ts       |       0 |        0 |       0 |       0 | 1-1181            
  ...ionCleanup.ts |   94.58 |    87.69 |     100 |   94.58 | ...74-175,256-257 
  sessionUtils.ts  |    9.23 |      100 |       0 |    9.23 | 43-99,106-120     
  settingsUtils.ts |   84.14 |    90.52 |   93.33 |   84.14 | ...12-439,478-479 
  ...ttingSaver.ts |    1.92 |      100 |       0 |    1.92 | 7-28,36-81        
  spawnWrapper.ts  |     100 |      100 |     100 |     100 |                   
  ...upWarnings.ts |     100 |      100 |     100 |     100 |                   
  ...entEmitter.ts |     100 |      100 |     100 |     100 |                   
  ...upWarnings.ts |     100 |      100 |     100 |     100 |                   
  version.ts       |     100 |       50 |     100 |     100 | 11                
  windowTitle.ts   |     100 |      100 |     100 |     100 |                   
 src/utils/privacy |    46.3 |    68.57 |   52.63 |    46.3 |                   
  ...taRedactor.ts |   60.66 |    70.58 |   55.55 |   60.66 | ...77-479,485-506 
  ...acyManager.ts |       0 |        0 |       0 |       0 | 1-178             
 ...ed-integration |   22.35 |        0 |       0 |   22.35 |                   
  acp.ts           |   14.63 |        0 |       0 |   14.63 | ...31-332,335-342 
  ...temService.ts |   20.58 |      100 |       0 |   20.58 | ...34,37-46,48-49 
  schema.ts        |     100 |      100 |     100 |     100 |                   
  ...ntegration.ts |    4.43 |      100 |       0 |    4.43 | ...1442,1457-1507 
-------------------|---------|----------|---------|---------|-------------------
Core Package - Full Text Report
-------------------|---------|----------|---------|---------|-------------------
File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------------|---------|----------|---------|---------|-------------------
All files          |   71.06 |    78.79 |   73.65 |   71.06 |                   
 src               |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
 src/__mocks__/fs  |       0 |        0 |       0 |       0 |                   
  promises.ts      |       0 |        0 |       0 |       0 | 1-48              
 src/adapters      |     100 |      100 |     100 |     100 |                   
  ...eamAdapter.ts |     100 |      100 |     100 |     100 |                   
 src/agents        |   77.47 |     68.1 |      90 |   77.47 |                   
  ...vestigator.ts |       0 |        0 |       0 |       0 | 1-152             
  executor.ts      |   88.23 |    67.03 |     100 |   88.23 | ...03-704,740-746 
  invocation.ts    |   96.34 |    76.47 |     100 |   96.34 | 61,65-66          
  registry.ts      |       0 |        0 |       0 |       0 | 1-83              
  types.ts         |     100 |      100 |     100 |     100 |                   
  utils.ts         |   78.94 |       80 |     100 |   78.94 | 32-35             
 src/auth          |   65.13 |    79.54 |   75.53 |   65.13 |                   
  ...evice-flow.ts |    7.21 |      100 |       0 |    7.21 | ...49-268,274-282 
  ...evice-flow.ts |   46.65 |    57.14 |   63.63 |   46.65 | ...95-484,494-580 
  oauth-errors.ts  |   94.15 |    83.33 |     100 |   94.15 | ...68,609,635-636 
  precedence.ts    |   76.75 |    78.15 |   94.44 |   76.75 | ...1028,1034-1037 
  ...evice-flow.ts |    8.33 |        0 |       0 |    8.33 | ...69-206,214-220 
  token-store.ts   |   77.96 |    88.09 |    90.9 |   77.96 | ...51-272,297-298 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/code_assist   |   68.18 |     79.6 |      78 |   68.18 |                   
  codeAssist.ts    |   16.25 |       50 |   33.33 |   16.25 | ...1,80-87,95-108 
  converter.ts     |    94.9 |    93.02 |     100 |    94.9 | ...84,198,215-216 
  ...al-storage.ts |     100 |    79.41 |     100 |     100 | 47-49,80-83       
  oauth2.ts        |    63.4 |    75.29 |   78.57 |    63.4 | ...16-717,722-723 
  server.ts        |   51.89 |    72.72 |   53.84 |   51.89 | ...99-240,243-246 
  setup.ts         |   82.92 |    73.91 |     100 |   82.92 | ...27-129,153-159 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/config        |   75.22 |    80.35 |    60.1 |   75.22 |                   
  config.ts        |   72.74 |    79.46 |   47.26 |   72.74 | ...1824,1830-1834 
  constants.ts     |     100 |      100 |     100 |     100 |                   
  endpoints.ts     |     100 |      100 |     100 |     100 |                   
  index.ts         |     100 |      100 |     100 |     100 |                   
  models.ts        |     100 |      100 |     100 |     100 |                   
  ...ileManager.ts |    94.8 |    85.07 |     100 |    94.8 | ...57-358,364,367 
  storage.ts       |   93.25 |    95.65 |   91.66 |   93.25 | 27-28,49-50,75-76 
  ...entManager.ts |   57.91 |    65.57 |     100 |   57.91 | ...57-458,476-500 
  types.ts         |       0 |        0 |       0 |       0 |                   
 ...nfirmation-bus |   70.23 |    88.46 |   72.72 |   70.23 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-2               
  message-bus.ts   |   69.42 |    91.66 |      80 |   69.42 | ...91-225,234-242 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/core          |   65.54 |    72.96 |   69.55 |   65.54 |                   
  baseLlmClient.ts |   97.26 |       90 |     100 |   97.26 | 55-56,244-245     
  ...ntegration.ts |   96.29 |       95 |     100 |   96.29 | ...18-119,199-200 
  client.ts        |   66.92 |       79 |   69.23 |   66.92 | ...1988,1992-2003 
  ...ion-config.ts |     100 |      100 |     100 |     100 |                   
  ...tGenerator.ts |   91.08 |    80.76 |     100 |   91.08 | ...32,148,163-166 
  ...lScheduler.ts |    76.9 |    74.58 |   94.73 |    76.9 | ...1839,1843-1849 
  geminiChat.ts    |   47.71 |    57.07 |   53.75 |   47.71 | ...2744,2767-2768 
  geminiRequest.ts |     100 |      100 |     100 |     100 |                   
  ...nAIWrapper.ts |   88.88 |      100 |   83.33 |   88.88 | 56-59             
  logger.ts        |   81.26 |    81.81 |     100 |   81.26 | ...64-378,419-430 
  ...tGenerator.ts |   10.89 |      100 |       0 |   10.89 | ...93-194,197-200 
  ...olExecutor.ts |   63.28 |    62.74 |   65.21 |   63.28 | ...06-440,449-465 
  prompts.ts       |   65.07 |    62.96 |      60 |   65.07 | ...81,297,335-388 
  subagent.ts      |   55.76 |    65.87 |   58.49 |   55.76 | ...1820,1832-1833 
  ...chestrator.ts |    89.1 |    73.56 |   95.23 |    89.1 | ...17,620-621,626 
  ...tScheduler.ts |       0 |        0 |       0 |       0 | 1                 
  tokenLimits.ts   |   90.27 |    73.07 |     100 |   90.27 | ...72,77,79,83,93 
  ...Governance.ts |    94.2 |     90.9 |     100 |    94.2 | 34-35,51-52       
  turn.ts          |   88.42 |    73.21 |     100 |   88.42 | ...24-425,455-456 
 src/debug         |   78.24 |    87.85 |   90.19 |   78.24 |                   
  ...ionManager.ts |   78.12 |     77.5 |   88.88 |   78.12 | ...21-222,239-243 
  DebugLogger.ts   |   89.47 |    89.28 |      85 |   89.47 | ...77,214,270-273 
  FileOutput.ts    |   96.82 |    95.23 |     100 |   96.82 | 82-83,107-108     
  ...ionManager.ts |       0 |      100 |     100 |       0 | 18-64             
  ...FileOutput.ts |       0 |      100 |     100 |       0 | 15-37             
  index.ts         |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 |                   
 src/filters       |   99.15 |    98.76 |     100 |   99.15 |                   
  EmojiFilter.ts   |   99.15 |    98.76 |     100 |   99.15 | 190-191           
 src/hooks         |   88.88 |    33.33 |     100 |   88.88 |                   
  ...ssion-hook.ts |   88.88 |    33.33 |     100 |   88.88 | 24,30             
 src/ide           |   72.88 |    84.61 |      74 |   72.88 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  detect-ide.ts    |     100 |      100 |     100 |     100 |                   
  ide-client.ts    |   54.56 |    75.51 |   56.66 |   54.56 | ...62-470,498-506 
  ide-installer.ts |   90.55 |    85.18 |     100 |   90.55 | ...35,142-146,159 
  ideContext.ts    |    83.8 |      100 |     100 |    83.8 | 75-91             
  process-utils.ts |   89.13 |    82.14 |     100 |   89.13 | ...69-170,211-212 
 src/interfaces    |       0 |        0 |       0 |       0 |                   
  index.ts         |       0 |        0 |       0 |       0 |                   
  ....interface.ts |       0 |        0 |       0 |       0 |                   
 src/mcp           |    78.5 |    77.04 |   71.95 |    78.5 |                   
  ...oken-store.ts |   87.38 |    90.47 |   81.25 |   87.38 | ...33-334,337-338 
  ...h-provider.ts |   83.01 |      100 |      25 |   83.01 | ...69,73,77,81-82 
  ...h-provider.ts |   73.14 |    53.68 |     100 |   73.14 | ...04-811,818-820 
  ...en-storage.ts |    81.5 |    88.88 |   68.18 |    81.5 | ...95-196,201-202 
  oauth-utils.ts   |   70.33 |    81.48 |    90.9 |   70.33 | ...62-283,308-331 
  ...n-provider.ts |   89.28 |    95.65 |      40 |   89.28 | ...37,141,145-146 
  token-store.ts   |     100 |      100 |     100 |     100 |                   
 .../token-storage |   90.08 |    86.86 |   95.34 |   90.08 |                   
  ...en-storage.ts |     100 |      100 |     100 |     100 |                   
  ...en-storage.ts |   86.61 |    87.09 |   92.85 |   86.61 | ...64-172,180-181 
  ...en-storage.ts |     100 |      100 |     100 |     100 |                   
  ...en-storage.ts |   87.43 |    80.82 |    92.3 |   87.43 | ...20,222,274-275 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/parsers       |   68.08 |       75 |   83.33 |   68.08 |                   
  ...CallParser.ts |   68.08 |       75 |   83.33 |   68.08 | ...1018,1024-1039 
 src/policy        |    88.1 |    81.29 |   86.95 |    88.1 |                   
  config.ts        |   91.01 |    84.21 |     100 |   91.01 | ...05,150,155-157 
  index.ts         |       0 |        0 |       0 |       0 | 1-5               
  policy-engine.ts |     100 |    97.67 |     100 |     100 | 23                
  ...-stringify.ts |   80.23 |    60.52 |      50 |   80.23 | ...22-126,139-140 
  toml-loader.ts   |   87.16 |    83.78 |     100 |   87.16 | ...03-204,215-223 
  types.ts         |     100 |      100 |     100 |     100 |                   
 src/prompt-config |   74.73 |    84.18 |    87.8 |   74.73 |                   
  ...lateEngine.ts |    93.9 |    88.52 |     100 |    93.9 | ...29,165,172,192 
  index.ts         |       0 |      100 |     100 |       0 | 5-41              
  prompt-cache.ts  |   99.04 |    97.26 |     100 |   99.04 | 204-205           
  ...-installer.ts |   83.11 |    82.53 |     100 |   83.11 | ...1173,1253-1254 
  prompt-loader.ts |   87.27 |    90.42 |   76.92 |   87.27 | ...22-423,429-430 
  ...t-resolver.ts |   34.85 |    64.17 |   53.84 |   34.85 | ...20-771,774-802 
  ...pt-service.ts |   84.49 |     83.5 |   93.75 |   84.49 | ...21,550,562-563 
  types.ts         |     100 |      100 |     100 |     100 |                   
 ...onfig/defaults |   50.11 |    46.75 |     100 |   50.11 |                   
  core-defaults.ts |    37.3 |    39.02 |     100 |    37.3 | ...72,283,289-297 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...est-loader.ts |   81.81 |    79.31 |     100 |   81.81 | ...02-108,116-120 
  ...t-warnings.ts |      92 |    33.33 |     100 |      92 | 17-18             
  ...r-defaults.ts |    41.7 |    39.02 |     100 |    41.7 | ...40,251,257-262 
  ...e-defaults.ts |     100 |      100 |     100 |     100 |                   
  tool-defaults.ts |      50 |       40 |     100 |      50 | ...11-216,229-234 
 src/prompts       |   26.41 |      100 |      25 |   26.41 |                   
  mcp-prompts.ts   |   18.18 |      100 |       0 |   18.18 | 11-19             
  ...t-registry.ts |   28.57 |      100 |   28.57 |   28.57 | ...42,48-55,68-73 
 src/providers     |   68.76 |    77.34 |   67.21 |   68.76 |                   
  BaseProvider.ts  |   80.78 |    79.46 |   80.76 |   80.78 | ...1154,1191-1192 
  ...eratorRole.ts |     100 |      100 |     100 |     100 |                   
  IModel.ts        |       0 |        0 |       0 |       0 |                   
  IProvider.ts     |       0 |        0 |       0 |       0 |                   
  ...derManager.ts |     100 |      100 |     100 |     100 |                   
  ITool.ts         |       0 |        0 |       0 |       0 |                   
  ...ngProvider.ts |   87.91 |    88.61 |   90.62 |   87.91 | ...1106,1137-1139 
  ...derWrapper.ts |   56.67 |     64.4 |   51.28 |   56.67 | ...1355,1362-1369 
  ...tGenerator.ts |    17.3 |      100 |       0 |    17.3 | ...59,62-79,82-85 
  ...derManager.ts |   60.16 |    72.96 |   60.46 |   60.16 | ...1437-1438,1441 
  errors.ts        |   78.57 |    63.63 |      60 |   78.57 | ...43,150-170,191 
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 ...ders/anthropic |   74.17 |    77.48 |   74.54 |   74.17 |                   
  ...icProvider.ts |   76.27 |    80.85 |      75 |   76.27 | ...2349,2357-2358 
  ...aConverter.ts |   51.61 |    40.62 |   71.42 |   51.61 | ...52,258,272-280 
 ...oviders/gemini |   56.39 |    67.94 |   48.78 |   56.39 |                   
  ...niProvider.ts |   51.86 |    56.97 |   46.15 |   51.86 | ...1866,1875-1876 
  ...Signatures.ts |     100 |    98.38 |     100 |     100 | 182               
 ...viders/logging |   39.53 |       80 |      75 |   39.53 |                   
  ...tExtractor.ts |       0 |        0 |       0 |       0 | 1-228             
  ...nceTracker.ts |   89.47 |    84.21 |   81.81 |   89.47 | ...66-167,182-183 
 ...oviders/openai |   51.72 |    73.89 |   60.49 |   51.72 |                   
  ...ationCache.ts |   70.49 |    86.66 |   82.35 |   70.49 | ...64-166,216-217 
  ...rateParams.ts |       0 |        0 |       0 |       0 |                   
  ...AIProvider.ts |   39.18 |    63.97 |   45.55 |   39.18 | ...4932,4940-4949 
  ...API_MODELS.ts |     100 |      100 |     100 |     100 |                   
  ...lCollector.ts |   93.13 |    88.46 |     100 |   93.13 | ...46-148,168-169 
  ...Normalizer.ts |   92.64 |    95.83 |     100 |   92.64 | 71-75             
  ...llPipeline.ts |   64.22 |    53.33 |      75 |   64.22 | ...33-142,173-183 
  ...eValidator.ts |   94.02 |    93.75 |     100 |   94.02 | 106-109           
  ...sesRequest.ts |   83.56 |    93.24 |     100 |   83.56 | ...60,293,298-303 
  ...moteTokens.ts |   89.55 |     92.3 |     100 |   89.55 | 101-107           
  ...oviderInfo.ts |    86.2 |    73.52 |     100 |    86.2 | ...31-133,144-145 
  ...uestParams.ts |   93.81 |     82.6 |     100 |   93.81 | ...,95-96,105-106 
  ...nsesStream.ts |   88.43 |    86.66 |     100 |   88.43 | ...80,203-210,234 
  ...aConverter.ts |    24.2 |    42.85 |   28.57 |    24.2 | ...59-260,277-285 
  ...lResponses.ts |   71.98 |    73.91 |      75 |   71.98 | ...97-301,321-335 
  test-types.ts    |       0 |        0 |       0 |       0 |                   
  toolNameUtils.ts |   96.79 |    95.45 |      50 |   96.79 | 102,127,239-241   
 ...enai-responses |   63.69 |    74.07 |   43.75 |   63.69 |                   
  CODEX_MODELS.ts  |     100 |      100 |     100 |     100 |                   
  CODEX_PROMPT.ts  |   33.33 |      100 |       0 |   33.33 | 36-39             
  ...esProvider.ts |   75.67 |    78.37 |   54.54 |   75.67 | ...25,841,845-846 
  ...romContent.ts |   84.93 |    66.66 |     100 |   84.93 | 45-49,71-75,94    
  index.ts         |       0 |        0 |       0 |       0 | 1                 
  ...aConverter.ts |    8.12 |       20 |   14.28 |    8.12 | ...53-277,280-289 
 .../openai-vercel |   66.81 |    67.42 |   66.66 |   66.81 |                   
  ...elProvider.ts |   63.81 |     64.9 |   54.34 |   63.81 | ...1934,1944-1999 
  errors.ts        |   93.23 |    82.05 |     100 |   93.23 | ...50-151,165-169 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...Conversion.ts |   71.63 |    73.17 |   83.33 |   71.63 | ...45,548-549,553 
  ...aConverter.ts |   50.95 |       40 |   71.42 |   50.95 | ...58-259,276-284 
  toolIdUtils.ts   |   86.15 |    84.37 |     100 |   86.15 | ...,94-95,116-117 
 ...ders/reasoning |    42.1 |       90 |      70 |    42.1 |                   
  ...oningUtils.ts |    42.1 |       90 |      70 |    42.1 | ...45-203,235-310 
 ...ers/test-utils |     100 |      100 |     100 |     100 |                   
  ...TestConfig.ts |     100 |      100 |     100 |     100 |                   
 ...ers/tokenizers |    66.1 |    55.55 |      75 |    66.1 |                   
  ...cTokenizer.ts |   57.89 |       25 |     100 |   57.89 | 28-29,34-39       
  ITokenizer.ts    |       0 |        0 |       0 |       0 |                   
  ...ITokenizer.ts |      70 |       80 |   66.66 |      70 | 52-55,62-71       
 ...roviders/types |       0 |        0 |       0 |       0 |                   
  ...iderConfig.ts |       0 |        0 |       0 |       0 |                   
  ...derRuntime.ts |       0 |        0 |       0 |       0 |                   
 ...roviders/utils |   85.64 |    87.01 |      96 |   85.64 |                   
  authToken.ts     |   33.33 |       50 |      50 |   33.33 | 14-22,30-35       
  ...sExtractor.ts |   95.45 |     91.3 |     100 |   95.45 | 15-16             
  dumpContext.ts   |    96.1 |    95.65 |     100 |    96.1 | 110-112           
  ...SDKContext.ts |   94.59 |       75 |     100 |   94.59 | 27,49             
  localEndpoint.ts |   89.28 |    91.42 |     100 |   89.28 | ...18-119,138-139 
  ...malization.ts |   79.41 |    92.85 |     100 |   79.41 | 59-66             
  ...nsePayload.ts |   91.05 |    82.92 |     100 |   91.05 | 60-65,115-119     
  userMemory.ts    |   51.51 |    66.66 |     100 |   51.51 | 16-18,31-43       
 src/runtime       |   84.52 |    85.93 |   74.28 |   84.52 |                   
  ...imeContext.ts |     100 |      100 |     100 |     100 |                   
  ...timeLoader.ts |      85 |    71.42 |      80 |      85 | ...87-190,228-231 
  ...ntimeState.ts |   95.22 |       92 |     100 |   95.22 | ...35-636,652-653 
  ...ionContext.ts |   80.35 |    92.85 |      75 |   80.35 | 64-66,110-117     
  ...imeContext.ts |   89.69 |      100 |   58.33 |   89.69 | ...96,103,111-113 
  index.ts         |       0 |        0 |       0 |       0 | 1-15              
  ...imeContext.ts |    64.7 |    83.33 |     100 |    64.7 | 67-78,83-94       
  ...meAdapters.ts |   54.95 |    68.75 |   43.75 |   54.95 | ...98-108,125-152 
  ...ateFactory.ts |    96.9 |    86.48 |     100 |    96.9 | 95,110,136        
 src/services      |   81.53 |    84.27 |   75.96 |   81.53 |                   
  ...ardService.ts |   93.33 |    92.85 |     100 |   93.33 | 63,67-68          
  ...y-analyzer.ts |   76.32 |    81.17 |   77.77 |   76.32 | ...79-507,513-514 
  ...eryService.ts |   96.29 |    84.21 |     100 |   96.29 | 41,50,100-101     
  ...temService.ts |    61.9 |      100 |   66.66 |    61.9 | 54-61             
  ...ts-service.ts |      50 |      100 |       0 |      50 | 41-42,48-49       
  gitService.ts    |   70.58 |    93.33 |      60 |   70.58 | ...16-126,129-133 
  index.ts         |       0 |        0 |       0 |       0 | 1-15              
  ...ionService.ts |   99.04 |    98.41 |     100 |   99.04 | 270-271           
  ...ionService.ts |   89.31 |    84.21 |    92.3 |   89.31 | ...09,614,623-639 
  ...xt-tracker.ts |   94.87 |       90 |    87.5 |   94.87 | 54-55             
  ...er-service.ts |      42 |     90.9 |      25 |      42 | ...37-140,143-161 
  ...er-service.ts |   69.45 |    55.88 |      80 |   69.45 | ...85-289,311-314 
 ...rvices/history |   79.01 |    82.92 |   77.77 |   79.01 |                   
  ...Converters.ts |   79.88 |    80.31 |      75 |   79.88 | ...58-364,430-453 
  HistoryEvents.ts |       0 |        0 |       0 |       0 |                   
  ...oryService.ts |   79.17 |    83.58 |   86.53 |   79.17 | ...1329,1365-1366 
  IContent.ts      |   73.56 |    92.85 |   36.36 |   73.56 | ...32,299,309-329 
 src/settings      |   92.48 |    77.02 |      92 |   92.48 |                   
  ...ngsService.ts |   91.69 |       75 |   95.23 |   91.69 | ...53-354,384-388 
  ...ceInstance.ts |     100 |      100 |     100 |     100 |                   
  types.ts         |       0 |        0 |       0 |       0 | 1                 
 src/storage       |   93.53 |    93.02 |   94.44 |   93.53 |                   
  ...FileWriter.ts |   83.54 |       80 |    87.5 |   83.54 | 40-41,71-81       
  ...nceService.ts |   98.67 |    96.96 |     100 |   98.67 | 293-294           
  sessionTypes.ts  |     100 |      100 |     100 |     100 |                   
 src/telemetry     |   65.88 |    79.89 |   60.33 |   65.88 |                   
  constants.ts     |     100 |      100 |     100 |     100 |                   
  ...-exporters.ts |   28.08 |      100 |       0 |   28.08 | ...14-115,118-119 
  index.ts         |     100 |      100 |     100 |     100 |                   
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-17              
  ...t.circular.ts |       0 |        0 |       0 |       0 | 1-132             
  loggers.ts       |   64.38 |    69.76 |   59.25 |   64.38 | ...70-583,591-607 
  metrics.ts       |   62.35 |    96.15 |   66.66 |   62.35 | ...41-163,166-189 
  sdk.ts           |   72.54 |    23.07 |     100 |   72.54 | ...35,140-141,143 
  ...l-decision.ts |   33.33 |      100 |       0 |   33.33 | 17-32             
  types.ts         |   73.94 |     84.7 |   64.91 |   73.94 | ...34-636,639-643 
  uiTelemetry.ts   |   95.26 |    96.42 |   91.66 |   95.26 | 152,189-195       
 src/test-utils    |   86.61 |    82.35 |   57.95 |   86.61 |                   
  config.ts        |     100 |      100 |     100 |     100 |                   
  index.ts         |       0 |        0 |       0 |       0 | 1-9               
  mock-tool.ts     |   95.06 |    93.33 |   83.33 |   95.06 | 62-63,118-119     
  ...aceContext.ts |     100 |      100 |     100 |     100 |                   
  ...allOptions.ts |   93.45 |    90.69 |   63.63 |   93.45 | ...07,171,200-203 
  runtime.ts       |   80.18 |       70 |   39.53 |   80.18 | ...99-301,310-312 
  tools.ts         |      82 |    76.92 |   78.94 |      82 | ...31,153,157-158 
 src/todo          |   56.28 |    81.48 |      75 |   56.28 |                   
  todoFormatter.ts |   56.28 |    81.48 |      75 |   56.28 | ...11-212,236-237 
 src/tools         |    76.2 |    78.05 |    79.7 |    76.2 |                   
  ...lFormatter.ts |     100 |      100 |     100 |     100 |                   
  ToolFormatter.ts |   20.89 |    76.19 |   33.33 |   20.89 | ...07,514-612,627 
  ...IdStrategy.ts |      95 |    92.85 |     100 |      95 | 237-239,250-252   
  codesearch.ts    |      98 |     87.5 |   85.71 |      98 | 110-111,173       
  ...line_range.ts |   84.68 |    67.56 |      70 |   84.68 | ...81-282,290-291 
  diffOptions.ts   |     100 |      100 |     100 |     100 |                   
  ...-web-fetch.ts |   93.14 |    72.41 |   77.77 |   93.14 | ...55,165-166,186 
  ...scapeUtils.ts |   61.65 |    72.97 |      50 |   61.65 | ...93,309,311-321 
  edit.ts          |   74.66 |    78.03 |   76.47 |   74.66 | ...68-769,782-823 
  ...web-search.ts |   97.91 |    85.71 |   83.33 |   97.91 | 126-127,191       
  ...y-replacer.ts |   85.71 |    84.35 |     100 |   85.71 | ...47-448,493-494 
  glob.ts          |   90.51 |    80.35 |   88.88 |   90.51 | ...51-252,351-352 
  ...-web-fetch.ts |   94.21 |    87.75 |    92.3 |   94.21 | ...66-367,468-469 
  ...invocation.ts |   54.74 |    38.88 |      75 |   54.74 | ...29-133,165-210 
  ...web-search.ts |     100 |      100 |     100 |     100 |                   
  grep.ts          |   59.01 |    77.34 |   72.22 |   59.01 | ...57-961,971-972 
  ...rt_at_line.ts |   81.55 |    76.08 |      70 |   81.55 | ...05-306,314-315 
  ...-subagents.ts |   87.28 |    69.56 |   88.88 |   87.28 | ...1,81-89,98,153 
  ls.ts            |   97.42 |    91.66 |     100 |   97.42 | 146-151           
  ...nt-manager.ts |   79.04 |    66.66 |      80 |   79.04 | ...31-138,146-147 
  mcp-client.ts    |   54.67 |     60.8 |   58.06 |   54.67 | ...1342,1346-1349 
  mcp-tool.ts      |   94.21 |    93.75 |   86.95 |   94.21 | ...39-249,311-312 
  memoryTool.ts    |   79.63 |    82.75 |    87.5 |   79.63 | ...55-356,399-439 
  ...iable-tool.ts |   98.34 |       80 |     100 |   98.34 | 168-169           
  read-file.ts     |   91.27 |    79.16 |    90.9 |   91.27 | ...26-227,393-394 
  ...many-files.ts |   71.42 |     77.5 |   88.88 |   71.42 | ...55-556,563-564 
  ...line_range.ts |    74.9 |     65.9 |      80 |    74.9 | ...50-351,355-356 
  ripGrep.ts       |   89.75 |    86.02 |    92.3 |   89.75 | ...47-448,469-470 
  shell.ts         |   80.82 |    79.48 |   84.21 |   80.82 | ...95-796,807-808 
  task.ts          |   80.63 |    68.67 |   92.85 |   80.63 | ...70,773,776-785 
  todo-events.ts   |    62.5 |      100 |       0 |    62.5 | 23-24,27-28,31-32 
  todo-pause.ts    |   87.09 |       80 |     100 |   87.09 | 64-69,73-78,93-98 
  todo-read.ts     |   85.29 |    95.45 |     100 |   85.29 | 112-113,123-138   
  todo-schemas.ts  |     100 |      100 |     100 |     100 |                   
  todo-store.ts    |   86.66 |       80 |     100 |   86.66 | 48-49,55-56,63-64 
  todo-write.ts    |   87.28 |    75.75 |    87.5 |   87.28 | ...17,264-265,290 
  ...tion-types.ts |     100 |      100 |     100 |     100 |                   
  tool-context.ts  |     100 |      100 |     100 |     100 |                   
  tool-error.ts    |   87.75 |      100 |       0 |   87.75 | 105-112           
  tool-names.ts    |     100 |      100 |     100 |     100 |                   
  tool-registry.ts |   72.28 |       71 |   73.68 |   72.28 | ...68-676,684-685 
  toolNameUtils.ts |      80 |     92.1 |     100 |      80 | 59-60,64-65,69-82 
  tools.ts         |   79.03 |    89.28 |   66.66 |   79.03 | ...32-733,736-740 
  write-file.ts    |   75.57 |    64.36 |   73.33 |   75.57 | ...04-605,614-653 
 src/types         |     100 |      100 |     100 |     100 |                   
  modelParams.ts   |     100 |      100 |     100 |     100 |                   
 src/utils         |   82.88 |    87.66 |    85.9 |   82.88 |                   
  LruCache.ts      |       0 |        0 |       0 |       0 | 1-41              
  bfsFileSearch.ts |   88.88 |       90 |     100 |   88.88 | 83-91             
  browser.ts       |    8.69 |      100 |       0 |    8.69 | 17-53             
  editor.ts        |   97.64 |    94.23 |     100 |   97.64 | 159,228,231-232   
  ...entContext.ts |     100 |      100 |     100 |     100 |                   
  errorParsing.ts  |      88 |    78.26 |     100 |      88 | ...07,249,252,258 
  ...rReporting.ts |   83.72 |    84.61 |     100 |   83.72 | 82-86,107-115     
  errors.ts        |   55.55 |    71.42 |   38.46 |   55.55 | ...92-108,112-118 
  fetch.ts         |   30.43 |    66.66 |   33.33 |   30.43 | 22-27,35-36,39-83 
  fileUtils.ts     |    95.2 |       90 |     100 |    95.2 | ...34-238,450-456 
  formatters.ts    |   54.54 |       50 |     100 |   54.54 | 12-16             
  ...eUtilities.ts |   96.11 |       96 |     100 |   96.11 | 36-37,67-68       
  ...rStructure.ts |   95.96 |    94.93 |     100 |   95.96 | ...14-117,345-347 
  getPty.ts        |    12.5 |      100 |       0 |    12.5 | 21-34             
  ...noreParser.ts |    91.6 |    85.18 |     100 |    91.6 | ...01-202,206-207 
  ...ineChanges.ts |   58.56 |    79.41 |      80 |   58.56 | ...18-256,264-270 
  gitUtils.ts      |   90.24 |    90.47 |     100 |   90.24 | 40-41,71-72       
  ide-trust.ts     |      60 |      100 |       0 |      60 | 14-15             
  ...rePatterns.ts |     100 |    96.55 |     100 |     100 | 248               
  ...ionManager.ts |     100 |       90 |     100 |     100 | 23                
  ...edit-fixer.ts |       0 |        0 |       0 |       0 | 1-156             
  ...yDiscovery.ts |   86.32 |    76.27 |   77.77 |   86.32 | ...02-403,406-407 
  ...tProcessor.ts |    93.4 |    86.51 |    92.3 |    93.4 | ...87-388,397-398 
  ...Inspectors.ts |   61.53 |      100 |      50 |   61.53 | 18-23             
  output-format.ts |   36.84 |      100 |       0 |   36.84 | 26-37             
  partUtils.ts     |     100 |      100 |     100 |     100 |                   
  pathReader.ts    |       0 |        0 |       0 |       0 | 1-60              
  paths.ts         |   85.32 |    84.37 |     100 |   85.32 | ...,98-99,110-111 
  ...rDetection.ts |   57.62 |    63.15 |     100 |   57.62 | ...9,92-93,99-100 
  retry.ts         |   69.49 |    79.16 |   81.81 |   69.49 | ...60-563,568-569 
  ...thResolver.ts |   84.31 |       84 |     100 |   84.31 | 62-73,96,145-148  
  ...nStringify.ts |     100 |      100 |     100 |     100 |                   
  sanitization.ts  |     100 |      100 |     100 |     100 |                   
  ...aValidator.ts |   83.52 |    82.75 |     100 |   83.52 | 70-81,125-126     
  ...r-launcher.ts |   78.57 |     87.5 |   66.66 |   78.57 | ...33,135,153-188 
  session.ts       |     100 |      100 |     100 |     100 |                   
  shell-markers.ts |     100 |      100 |     100 |     100 |                   
  shell-utils.ts   |   95.25 |    95.38 |     100 |   95.25 | ...94-195,326-331 
  summarizer.ts    |     100 |    88.88 |     100 |     100 | 92                
  ...emEncoding.ts |   97.14 |    91.42 |     100 |   97.14 | 108-109,161       
  testUtils.ts     |   53.33 |      100 |   33.33 |   53.33 | ...53,59-64,70-72 
  textUtils.ts     |    12.5 |      100 |       0 |    12.5 | 15-34             
  thoughtUtils.ts  |     100 |      100 |     100 |     100 |                   
  tool-utils.ts    |   91.48 |    89.47 |     100 |   91.48 | 52-53,56-57       
  ...putLimiter.ts |   85.22 |    76.31 |     100 |   85.22 | ...61-166,210-217 
  unicodeUtils.ts  |     100 |      100 |     100 |     100 |                   
  ...untManager.ts |   91.96 |    88.23 |     100 |   91.96 | 37-39,76-78,94-96 
  ...aceContext.ts |   96.82 |    95.34 |    92.3 |   96.82 | 94-95,109-110     
 ...ils/filesearch |   96.18 |    91.26 |     100 |   96.18 |                   
  crawlCache.ts    |     100 |      100 |     100 |     100 |                   
  crawler.ts       |   96.22 |     92.3 |     100 |   96.22 | 66-67             
  fileSearch.ts    |   93.22 |    86.95 |     100 |   93.22 | ...26-227,229-230 
  ignore.ts        |     100 |      100 |     100 |     100 |                   
  result-cache.ts  |     100 |    91.66 |     100 |     100 | 46                
-------------------|---------|----------|---------|---------|-------------------

For detailed HTML reports, please see the 'coverage-reports-24.x-ubuntu-latest' artifact from the main CI run.

@acoliver
Copy link
Collaborator Author

acoliver commented Jan 6, 2026

@CoreRabbit I don't see how this fully implements #920 as it just added the ephemerals but didn't add the optional parameters to the shell or task tool calls - am I wrong?

Completes issue #920 by adding the missing timeout_ms parameter to run_shell_command and task tools. PR #621 previously added the CLI ephemeral settings but the actual tool parameters were not implemented.

Changes:
- Added timeout_ms parameter to ShellToolParams and TaskToolParams interfaces
- Implemented timeout logic in both ShellToolInvocation and TaskToolInvocation following the GrepTool pattern:
  - Creates AbortController with setTimeout when timeout is specified
  - Reads default and max timeouts from ephemeral settings with hardcoded fallbacks
  - Handles -1 as unlimited (no timeout)
  - Clamps requested timeout to max setting
  - Combines user abort signal with timeout signal
  - Returns ToolResult with TIMEOUT error type on timeout (not EXECUTION_FAILED)
  - Includes partial output in timeout message
- Added comprehensive timeout tests for both tools:
  - Default timeout when parameter omitted
  - Max timeout enforcement (clamping)
  - -1 means unlimited
  - Returns TIMEOUT error type with partial output
  - Returns EXECUTION_FAILED for user aborts (distinct from timeout)
- Updated tool schemas to document timeout_ms parameter
- Integration with existing ephemeral settings (shell_default_timeout_ms, shell_max_timeout_ms, task_default_timeout_ms, task_max_timeout_ms)

All tests pass including timeout-specific test suites for both tools. The implementation distinguishes between timeout and user abort scenarios for clear error reporting.
closes #920
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
packages/core/src/tools/shell.ts (2)

269-282: Minor: Unnecessary removeEventListener call before listener is added.

At line 271, signal.removeEventListener('abort', onUserAbort) is called before the listener is actually added at line 282. While this is harmless (removing a non-existent listener is a no-op), it's unnecessary and slightly confusing. Consider removing line 271 or restructuring the flow for clarity.

🔎 Suggested simplification
     if (signal.aborted) {
       onUserAbort();
-      signal.removeEventListener('abort', onUserAbort);
       return {
         llmContent: 'Command was cancelled by user before it could start.',
         returnDisplay: 'Command cancelled by user.',
         error: {
           message: 'Command was cancelled by user before it could start.',
           type: ToolErrorType.EXECUTION_FAILED,
         },
       };
     }
 
     signal.addEventListener('abort', onUserAbort, { once: true });

516-530: Consider refactoring the nested ternary for readability.

The nested ternary operator spans multiple lines and is difficult to parse. Consider extracting this logic into a helper function or using early returns / if-else for clarity.

🔎 Proposed refactor
function determineExecutionError(
  result: ShellExecutionResult | null,
  timeoutController: AbortController,
  signal: AbortSignal,
  llmContent: string,
): { error?: { message: string; type: ToolErrorType } } {
  if (result?.error) {
    return {
      error: {
        message: result.error.message,
        type: ToolErrorType.SHELL_EXECUTE_ERROR,
      },
    };
  }
  if (result?.aborted && timeoutController.signal.aborted && !signal.aborted) {
    return {
      error: {
        message: llmContent,
        type: ToolErrorType.TIMEOUT,
      },
    };
  }
  if (result?.aborted) {
    return {
      error: {
        message: llmContent,
        type: ToolErrorType.EXECUTION_FAILED,
      },
    };
  }
  return {};
}
packages/core/src/tools/task.ts (1)

525-531: Minor type safety concern with ephemeral settings access.

The code casts ephemeral setting values to number | undefined:

(settings.task_default_timeout_ms as number | undefined)

While this works, consider adding a helper function or type guard to safely extract and validate numeric settings, especially since invalid values could come from user configuration.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 45297b1 and beef1eb.

📒 Files selected for processing (4)
  • packages/core/src/tools/shell.test.ts
  • packages/core/src/tools/shell.ts
  • packages/core/src/tools/task.test.ts
  • packages/core/src/tools/task.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Don't use any - Always specify proper types. Use unknown if the type is truly unknown and add proper type guards.
Do not use console.log or console.debug - Use the sophisticated logging system instead. Log files are written to ~/.llxprt/debug/
Fix all linting errors, including warnings about any types

Files:

  • packages/core/src/tools/task.test.ts
  • packages/core/src/tools/shell.test.ts
  • packages/core/src/tools/task.ts
  • packages/core/src/tools/shell.ts
🧠 Learnings (6)
📓 Common learnings
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-01-03T00:20:08.040Z
Learning: ShellExecutionService applies a hard cap only in the child_process path (appendAndTruncate, “16MB” message) and currently has no truncation in the PTY path, which can lead to unbounded memory before tool-level token limiting runs.
📚 Learning: 2025-12-26T14:17:41.983Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2025-12-26T14:17:41.983Z
Learning: In packages/core/src/core/coreToolScheduler.ts, the `publishBufferedResults()` method (line 1355) is called concurrently by multiple tool completion handlers (line 1510 in each tool's `.then()` callback) when parallel tools finish simultaneously. This causes a race condition where `nextPublishIndex` can be corrupted and tools can hang in 'executing' state forever, blocking the scheduler and causing subsequent tool calls to queue indefinitely. The method must be made reentrant-safe using a mutex/lock pattern to serialize concurrent calls.

Applied to files:

  • packages/core/src/tools/task.test.ts
  • packages/core/src/tools/task.ts
📚 Learning: 2025-11-16T22:51:26.374Z
Learnt from: e2720pjk
Repo: vybestack/llxprt-code PR: 583
File: packages/core/src/providers/openai/OpenAIProvider.ts:935-959
Timestamp: 2025-11-16T22:51:26.374Z
Learning: In the llxprt-code codebase (packages/core/src/providers/openai/OpenAIProvider.ts), tools like `run_shell_command` use internal streaming only for real-time UI updates during execution, but each tool execution produces exactly ONE final `ToolResponseBlock` containing the full result. The streaming chunks are never sent to the LLM and are not converted into multiple tool messages. The OpenAI Chat Completions API requires that each tool call (tool_call_id) corresponds to exactly one message with role 'tool', so duplicate tool response detection that removes subsequent tool messages with the same tool_call_id is correct and necessary for API compliance.

Applied to files:

  • packages/core/src/tools/task.test.ts
  • packages/core/src/tools/task.ts
  • packages/core/src/tools/shell.ts
📚 Learning: 2026-01-03T00:20:08.040Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-01-03T00:20:08.040Z
Learning: Shell tool (packages/core/src/tools/shell.ts) always applies tool-output-max-tokens via limitOutputTokens to the model-facing llmContent at the end of execute(), formatting a warning when truncated.

Applied to files:

  • packages/core/src/tools/shell.test.ts
  • packages/core/src/tools/shell.ts
📚 Learning: 2025-12-05T14:59:34.368Z
Learnt from: CR
Repo: vybestack/llxprt-code PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-05T14:59:34.368Z
Learning: Use subagents (general-purpose, typescript-code-reviewer, or typescript-coder) for complex multi-step tasks, research, complex implementations, code review, and extensive file searching

Applied to files:

  • packages/core/src/tools/task.ts
📚 Learning: 2026-01-03T00:20:08.040Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-01-03T00:20:08.040Z
Learning: ShellExecutionService applies a hard cap only in the child_process path (appendAndTruncate, “16MB” message) and currently has no truncation in the PTY path, which can lead to unbounded memory before tool-level token limiting runs.

Applied to files:

  • packages/core/src/tools/shell.ts
🧬 Code graph analysis (1)
packages/core/src/tools/task.ts (4)
packages/core/src/core/subagentOrchestrator.ts (1)
  • SubagentLaunchRequest (55-61)
packages/core/src/core/subagent.ts (1)
  • OutputObject (89-104)
packages/core/src/tools/tools.ts (1)
  • ToolResult (423-451)
packages/core/src/core/turn.ts (1)
  • DEFAULT_AGENT_ID (39-39)
⏰ Context from checks skipped due to timeout of 270000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Test (ubuntu-latest, 24.x)
  • GitHub Check: Test (windows-latest, 24.x)
  • GitHub Check: Test (macos-latest, 24.x)
  • GitHub Check: Slow E2E - Win
  • GitHub Check: E2E Test (Linux) - sandbox:docker
  • GitHub Check: E2E Test (Linux) - sandbox:none
🔇 Additional comments (26)
packages/core/src/tools/task.test.ts (6)

7-12: LGTM!

The afterEach and ToolErrorType imports are correctly added to support the new timeout handling tests.


91-94: LGTM!

The updated assertions correctly verify that runConfig includes the timeout (converted to minutes) and that an AbortSignal is passed to the orchestrator launch.


356-363: LGTM!

The test suite correctly sets up and tears down fake timers for timeout testing.


524-527: Verify the unlimited timeout assertion.

The assertion expect.not.objectContaining({ runConfig: expect.anything() }) expects no runConfig to be passed when timeout_ms is -1. However, looking at the implementation in task.ts, when timeoutMs is undefined (unlimited), createLaunchRequest returns a request without runConfig only if no timeout is set.

This may cause the test to fail if other parts of the code add runConfig for non-timeout purposes. Consider asserting specifically that runConfig.max_time_minutes is absent or undefined rather than that the entire runConfig is missing.


532-608: LGTM!

The TIMEOUT error test correctly simulates the timeout scenario by:

  1. Capturing the reject function from runInteractive
  2. Advancing timers past the timeout
  3. Manually triggering an AbortError to simulate the subagent detecting the abort

The test verifies that ToolErrorType.TIMEOUT is returned when the timeout triggers.


610-658: LGTM!

The user abort test correctly verifies that ToolErrorType.EXECUTION_FAILED is returned (not TIMEOUT) when the user aborts the signal before execution, ensuring proper distinction between timeout and user cancellation.

packages/core/src/tools/shell.ts (5)

47-48: LGTM!

The default (2 minutes) and max (10 minutes) timeout constants are reasonable defaults for shell command execution.


131-136: LGTM!

The timeout_ms parameter is correctly added as an optional number with appropriate documentation.


441-468: LGTM!

The timeout detection logic correctly distinguishes between:

  • Timeout: timeoutController.signal.aborted && !signal.aborted
  • User abort: The else branch handles user-initiated cancellation

The partial output is included in both cases as per the PR objectives.


599-618: LGTM!

The resolveTimeoutMs method correctly handles all timeout scenarios:

  • Returns undefined (unlimited) if requestedTimeoutMs or defaultTimeoutMs is -1
  • Skips clamping if maxTimeoutMs is -1
  • Clamps to maxTimeoutMs when the effective timeout exceeds it

This properly implements the -1/unlimited semantics per the PR objectives.


761-765: LGTM!

The schema correctly documents the timeout_ms parameter with the -1 for unlimited semantics.

packages/core/src/tools/shell.test.ts (6)

196-200: LGTM!

The assertions correctly updated to expect.any(AbortSignal) since the shell tool now passes a combined timeout/abort signal rather than the original user signal.

Also applies to: 231-235


348-368: LGTM!

The test correctly verifies that when timeout_ms is omitted, the default timeout from ephemeral settings (1234ms) is used to schedule the timeout.


370-393: LGTM!

The test correctly verifies that when timeout_ms (5000) exceeds the maximum setting (2000), the timeout is clamped to the maximum value.


395-418: LGTM!

The test correctly verifies that when timeout_ms is -1 (unlimited), no setTimeout is scheduled.


420-445: LGTM!

The test correctly verifies that when a timeout occurs:

  1. The error type is ToolErrorType.TIMEOUT
  2. The llmContent contains "timeout_ms" and partial output

The test advances time past the timeout, then resolves with aborted: true to simulate the shell service detecting the abort.


447-459: LGTM!

The test correctly verifies that user-initiated aborts (pre-aborted signal) result in ToolErrorType.EXECUTION_FAILED, not TIMEOUT, ensuring proper error classification.

packages/core/src/tools/task.ts (9)

33-34: LGTM!

The default (1 minute) and max (5 minutes) timeout constants are reasonable for task execution.


52-52: LGTM!

The timeout_ms parameter is correctly added as an optional number.


147-151: LGTM!

The timeout is correctly converted from milliseconds to minutes for the subagent's runConfig.max_time_minutes.


519-554: LGTM!

The createTimeoutControllers method correctly:

  1. Reads ephemeral settings with fallbacks to defaults
  2. Resolves the effective timeout using resolveTimeoutMs
  3. Creates an AbortController for timeout management
  4. Schedules the timeout (or skips if unlimited)
  5. Sets up user abort handling to clear timeout and propagate abort

556-575: LGTM!

The resolveTimeoutMs implementation correctly handles all -1/unlimited scenarios, matching the behavior in shell.ts. This addresses the concern from the past review comment.


577-589: LGTM!

The isTimeoutError method correctly identifies timeout scenarios by checking:

  1. timeoutController.signal.aborted is true
  2. signal.aborted (user signal) is false
  3. Any error is either absent or is an AbortError

This ensures user aborts are not misclassified as timeouts.


315-326: LGTM!

The teardown function properly cleans up resources:

  1. Removes the abort handler listener
  2. Removes the user abort listener
  3. Clears the timeout if set
  4. Disposes the subagent scope

All execution paths that reach this point use await teardown() before returning.


591-614: LGTM!

The createTimeoutResult method correctly creates a timeout error response with:

  • ToolErrorType.TIMEOUT error type
  • timedOut: true in metadata
  • Preservation of any emitted variables from partial execution

668-672: LGTM!

The schema correctly documents the timeout_ms parameter with the -1 for unlimited semantics.

… is added

CodeRabbit nitpick: The removeEventListener call at line 271 (before the listener is added at line 282) is unnecessary. While harmless (removing non-existent listener is no-op), it creates confusion. Removing it improves code clarity.
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI Agents
In @packages/core/src/tools/shell.ts:
- Around line 597-617: The resolveTimeoutMs helper currently returns any numeric
requestedTimeoutMs (including 0 or negative values other than -1), which allows
immediate timeouts; add validation so requestedTimeoutMs must be either
undefined, -1 (meaning no timeout), or a positive integer > 0. Implement this by
adding a guard either at the start of execute() (near the existing parameter
validation) or inside resolveTimeoutMs: if requestedTimeoutMs is a number and
requestedTimeoutMs !== -1 and requestedTimeoutMs <= 0, throw an error (or
reject) indicating invalid timeout_ms; then proceed to call resolveTimeoutMs as
before so only valid positive values (or -1/undefined) reach setTimeout. Ensure
references to resolveTimeoutMs and the execute method are updated accordingly.
🧹 Nitpick comments (1)
packages/core/src/tools/shell.ts (1)

515-529: Error type assignment is functionally correct.

The nested ternary correctly assigns ToolErrorType.TIMEOUT for timeout-triggered aborts and ToolErrorType.EXECUTION_FAILED for user-initiated aborts. Consider extracting this to a helper function for improved readability if the logic grows more complex.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between beef1eb and df47aa2.

📒 Files selected for processing (1)
  • packages/core/src/tools/shell.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Don't use any - Always specify proper types. Use unknown if the type is truly unknown and add proper type guards.
Do not use console.log or console.debug - Use the sophisticated logging system instead. Log files are written to ~/.llxprt/debug/
Fix all linting errors, including warnings about any types

Files:

  • packages/core/src/tools/shell.ts
🧠 Learnings (3)
📚 Learning: 2026-01-03T00:20:08.040Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-01-03T00:20:08.040Z
Learning: Shell tool (packages/core/src/tools/shell.ts) always applies tool-output-max-tokens via limitOutputTokens to the model-facing llmContent at the end of execute(), formatting a warning when truncated.

Applied to files:

  • packages/core/src/tools/shell.ts
📚 Learning: 2026-01-03T00:20:08.040Z
Learnt from: acoliver
Repo: vybestack/llxprt-code PR: 0
File: :0-0
Timestamp: 2026-01-03T00:20:08.040Z
Learning: ShellExecutionService applies a hard cap only in the child_process path (appendAndTruncate, “16MB” message) and currently has no truncation in the PTY path, which can lead to unbounded memory before tool-level token limiting runs.

Applied to files:

  • packages/core/src/tools/shell.ts
📚 Learning: 2025-11-16T22:51:26.374Z
Learnt from: e2720pjk
Repo: vybestack/llxprt-code PR: 583
File: packages/core/src/providers/openai/OpenAIProvider.ts:935-959
Timestamp: 2025-11-16T22:51:26.374Z
Learning: In the llxprt-code codebase (packages/core/src/providers/openai/OpenAIProvider.ts), tools like `run_shell_command` use internal streaming only for real-time UI updates during execution, but each tool execution produces exactly ONE final `ToolResponseBlock` containing the full result. The streaming chunks are never sent to the LLM and are not converted into multiple tool messages. The OpenAI Chat Completions API requires that each tool call (tool_call_id) corresponds to exactly one message with role 'tool', so duplicate tool response detection that removes subsequent tool messages with the same tool_call_id is correct and necessary for API compliance.

Applied to files:

  • packages/core/src/tools/shell.ts
⏰ Context from checks skipped due to timeout of 270000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: Test (windows-latest, 24.x)
  • GitHub Check: Test (ubuntu-latest, 24.x)
  • GitHub Check: Test (macos-latest, 24.x)
  • GitHub Check: E2E Test (Linux) - sandbox:none
  • GitHub Check: E2E Test (macOS)
  • GitHub Check: E2E Test (Linux) - sandbox:docker
  • GitHub Check: Slow E2E - Win
🔇 Additional comments (8)
packages/core/src/tools/shell.ts (8)

47-49: LGTM!

Sensible default values with clear naming. The numeric separators improve readability.


131-136: LGTM!

Interface property correctly defined as optional with appropriate documentation.


245-256: LGTM!

The timeout resolution logic correctly retrieves ephemeral settings and resolves the effective timeout. The type assertions are acceptable here given the dynamic nature of ephemeral settings.


257-283: LGTM!

The AbortController pattern is well-implemented:

  • Timeout is only set when timeoutMs is defined (finite).
  • The onUserAbort callback correctly clears the timeout to prevent dangling timers.
  • Using { once: true } for the event listener is a good practice.
  • Early abort handling correctly returns before registering listeners.

379-379: LGTM!

Correctly passes the combined signal to the execution service, allowing either timeout or user abort to cancel the operation.


440-467: LGTM!

The timeout detection logic (timeoutController.signal.aborted && !signal.aborted) correctly distinguishes between timeout and user-initiated abort. Partial output is properly included in both cases as required.


588-591: LGTM!

Comprehensive cleanup in the finally block ensures no resource leaks:

  • Timeout is cleared to prevent dangling timers.
  • Event listener is removed to prevent memory leaks.

760-764: LGTM with note on validation.

The schema correctly exposes timeout_ms as an optional numeric parameter. While JSON Schema constraints like minimum could be added, runtime validation in code (as suggested above) is the reliable approach since LLMs may not always respect schema constraints.

Comment on lines +597 to +617

private resolveTimeoutMs(
requestedTimeoutMs: number | undefined,
defaultTimeoutMs: number,
maxTimeoutMs: number,
): number | undefined {
if (requestedTimeoutMs === -1 || defaultTimeoutMs === -1) {
return undefined;
}

const effectiveTimeout = requestedTimeoutMs ?? defaultTimeoutMs;
if (maxTimeoutMs === -1) {
return effectiveTimeout;
}

if (effectiveTimeout > maxTimeoutMs) {
return maxTimeoutMs;
}

return effectiveTimeout;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Missing validation for timeout_ms parameter can cause immediate timeouts.

The resolveTimeoutMs method does not validate the requestedTimeoutMs value. If an LLM passes timeout_ms: 0 or a negative value other than -1, the method will return that value, causing setTimeout to fire immediately (since JavaScript treats zero/negative delays as zero).

For example:

  • timeout_ms: 0 → returns 0 → immediate timeout
  • timeout_ms: -5 → returns -5 → immediate timeout (negative treated as 0 by setTimeout)

Add validation in the execute() method or within resolveTimeoutMs to reject invalid values:

🔎 Proposed fix

Add validation at the start of the execute() method alongside other parameter validations (around line 239):

     if (this.params.grep_flags) {
       validateGrepFlags(this.params.grep_flags);
     }
+    if (
+      this.params.timeout_ms !== undefined &&
+      this.params.timeout_ms !== -1 &&
+      (!Number.isInteger(this.params.timeout_ms) || this.params.timeout_ms <= 0)
+    ) {
+      throw new Error(
+        `timeout_ms must be a positive integer or -1 (unlimited), got: ${this.params.timeout_ms}`,
+      );
+    }

     const strippedCommand = stripShellWrapper(this.params.command);

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In @packages/core/src/tools/shell.ts around lines 597 - 617, The
resolveTimeoutMs helper currently returns any numeric requestedTimeoutMs
(including 0 or negative values other than -1), which allows immediate timeouts;
add validation so requestedTimeoutMs must be either undefined, -1 (meaning no
timeout), or a positive integer > 0. Implement this by adding a guard either at
the start of execute() (near the existing parameter validation) or inside
resolveTimeoutMs: if requestedTimeoutMs is a number and requestedTimeoutMs !==
-1 and requestedTimeoutMs <= 0, throw an error (or reject) indicating invalid
timeout_ms; then proceed to call resolveTimeoutMs as before so only valid
positive values (or -1/undefined) reach setTimeout. Ensure references to
resolveTimeoutMs and the execute method are updated accordingly.

@acoliver acoliver merged commit 7c76cc5 into main Jan 6, 2026
19 of 20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintainer:e2e:ok Trusted contributor; maintainer-approved E2E run

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add tool-level timeouts for ShellTool (run_shell_command) and TaskTool

2 participants