Commit Graph

70 Commits

Author SHA1 Message Date
can1357 f8dbb3669f feat(utils): implemented windows shell resolution for bash execution
- Added resolveWindowsShell to locate Git Bash, scoop installs, and path binaries with a fallback to cmd.exe.
- Updated bash-executor to prevent wrapping user commands in cmd.exe when using fallback shell paths.
- Updated installation script to report optional shell status rather than failing when bash is absent.
2026-07-26 20:27:16 +02:00
roboomp 31098f9248 fix(tools): closed spilled output descriptors on error/abort paths
OutputSink.dump() was the only path that closed the spill Bun.FileSink.
The bash and Python executors re-throw on failure and their finally
blocks never closed the sink, so any large-output command that errored
leaked the artifact descriptor until an unrelated read (e.g. a SKILL.md
load) hit EMFILE.

Added an idempotent OutputSink.dispose() that closes the sink exactly
once (awaiting any in-flight sink creation, guarding post-finalize
resurrection) and wired it into every executor's finally block.

Fixes #6463
2026-07-24 03:44:12 +00:00
can1357 4838ec3686 Merge PR #4455: feat(coding-agent): auto-load direnv environment into the bash session (@mattwilkinsonn)
# Conflicts:
#	packages/coding-agent/src/exec/bash-executor.ts
#	packages/coding-agent/test/bash-executor.test.ts
2026-07-23 17:38:28 +02:00
can1357 3c6ade647b Merge PR #4784: fix(coding-agent): persist bash shortcut cwd changes (@jeffscottward) 2026-07-20 22:50:05 +02:00
iacore eb6ba80420 fix(coding-agent): run fish user shell interactively instead of as a login shell
The interactive !/!! shortcut wrapped commands as `fish -l -c '…'`:
resolveUserShellConfig swaps in $SHELL but inherits the bash-oriented
["-l", "-c"] args, and ensureInteractiveShellArgs injected -i only
for zsh. A login fish fires `status is-login` blocks in user config
(agent/keychain setup, PATH mutation) on every command.

fish sources the same config.fish/conf.d files for interactive shells
as for login shells, so give fish -i and strip the inherited -l: user
aliases and functions (#1816) keep working without login-shell side
effects. zsh keeps -l -i since .zprofile is login-only.
2026-07-19 14:34:10 +08:00
Jeff Scott Ward 3e24087111 fix(coding-agent): persist bash shortcut cwd changes 2026-07-17 16:58:32 -04:00
can1357 ab39a4b18b Merge branch 'sweep/2026-07-17' into eval/pr-5546 2026-07-17 05:22:13 +02:00
can1357 a4c9ffb434 fix: preserve bash timeout and abort semantics 2026-07-17 05:18:39 +02:00
can1357 4d7e51413b merge PR #5671 via eval/pr-5671: fix(bash): drained piped output before timeout return 2026-07-17 04:37:11 +02:00
roboomp 3e38a5b514 fix(bash): drained piped output before timeout return
- Delayed reader cancellation so pipeline consumers can flush after producers are terminated.
- Kept the JavaScript watchdog behind bounded native timeout cleanup.
- Added native and executor regressions for timeout-time output draining.

Fixes #5316
2026-07-16 07:22:58 +00:00
oldschoola 596a20517f fix: render bash timeout with warning border instead of error
Bash command timeouts now render with a warning (yellow) border instead
of an error (red) border, reflecting that the timeout ran its course
rather than the command failing.

The timeout is no longer thrown as a ToolError — instead #buildCompletedResult
returns a non-throwing error result (isError=true, keeping the model-facing
contract) with details.timedOut=true. The renderer reads this flag to pick
state="warning" (yellow) instead of state="error" (red).

The timedOut flag is propagated from bash-executor.ts, which now sets
timedOut=true on timeout return paths and leaves it unset on user-abort
paths. This distinguishes timeouts from user Esc-cancels — previously both
returned cancelled=true with no way to tell them apart in bash.ts.
2026-07-14 20:21:59 -07:00
roboomp a9e6e4e67e fix(bash): aborted isolated shells on cancellation
Route overlapping executions through owned Shell instances so timeout and interrupt paths can explicitly abort native child-process cleanup.

Fixes #5389
2026-07-14 19:57:59 +00:00
roboomp 9002f4ff0a fix(bash): avoided aborting native timeout signal
Prevented explicit bash timeouts from also aborting the AbortSignal passed to pi-natives while streamed output is still draining. Native timeout_ms now owns cancellation, and the JavaScript timer only reports the fallback timeout result.

Added regression coverage for streamed output before an explicit timeout.

Fixes #5021
2026-07-10 03:48:40 +00:00
Matt Wilkinson 33318cf5e1 fix(direnv): clamp the ACP/PTY backend preflight to the caller timeout
The executeBash direnv preflight clamps its load budget to a positive
caller command timeout, but the PTY / ACP-terminal backend preflight in
bash.ts passed the raw bash.direnvLoadTimeoutMs (30s default) with no
clamp — so a short-timeout command routed through those backends could
hang up to 30s on a cold `.envrc` before its own timeout is even
installed. Centralize the clamp inside applyDirenvPreflight (new
callerTimeoutMs option) so every backend inherits one contract:
`timeout: 0`/undefined keeps the full budget, a positive deadline clamps.

Co-Authored-By: seal <noreply@sealedsecurity.com>
2026-07-09 01:35:17 -04:00
Matt Wilkinson 5941d797ba feat(direnv): apply devenv env across all bash backends + always revalidate
Extract applyDirenvPreflight() so the ACP client terminal and PTY backends
get the same direnv/devenv overlay as executeBash (previously only the
one-shot path did). The helper is a pure (command, env) transform — merge
direnv's set under the caller's overlay, prepend a regex-gated unset -v for
removed vars — so interactive backends keep their own env shape (live TERM)
while executeBash still layers its non-interactive defaults on top. The three
dispatch branches are mutually exclusive, so no command is preflighted twice.

Also drop the content-hash export cache in loadDirenvEnv: always run
direnv export json and let direnv's own watch/mtime invalidation decide
freshness, so a changed watched file re-exports even when .envrc is unchanged.

Co-Authored-By: seal <noreply@sealedsecurity.com>
2026-07-08 23:55:19 -04:00
Matt Wilkinson 5ea0cc8419 fix(direnv): drain stderr, honor cancellation, and apply unsets in bash direnv preflight
Drain stdout and stderr concurrently so a cold .envrc/devenv load can't fill the stderr pipe and block until the timeout cap. Thread the caller's abort signal and per-call timeout into the direnv preflight (AbortSignal.any + min timeout) so an aborted or short-timeout bash call returns promptly. Return the full direnv export diff and honor variable *removals*: the per-command env overlay can only add/override, so prepend a shell-level 'unset -v' for direnv's unset list, gated by a POSIX-identifier regex and skipped when the caller re-supplied the var. Tests: skip the real-direnv cases when direnv is absent, and isolate HOME/XDG so 'direnv allow' never writes into the developer's global store; add unset coverage.
2026-07-08 23:48:05 -04:00
Matt Wilkinson 47493b0742 feat(coding-agent): auto-load direnv environment into the bash session
The bash tool's persistent shell didn't carry a repo's direnv/devenv
environment, so devenv-provided tools (moon, project-pinned biome/bun,
toolchains) were off PATH and .envrc-set vars (e.g. GIT_DIR for a jj
secondary workspace) were missing. Resolve the nearest .envrc from the
run cwd, load its env via direnv export json, and merge it under the
caller's per-call env. Gated by bash.direnv (default auto, auto-allows).
2026-07-08 23:48:05 -04:00
Christian Stewart 78d4978c51 fix(bash): support disabled command deadlines
Treat timeout 0 as an explicit no-deadline contract across the bash tool, executor, async job, and PTY paths.

Signed-off-by: Christian Stewart <christian@aperture.us>
2026-07-05 16:03:37 -07:00
Jeff Scott Ward 3da25618ea fix: preserve bash cwd without pwd probe 2026-06-30 23:51:28 -04:00
roboomp dff941d5fe fix(coding-agent): preserved bash status while syncing cwd
Propagated the native shell working directory in ShellRunResult so AgentSession can refresh cwd without running a hidden pwd command in the persistent shell.

Added regression coverage for cd plus a failing command followed by echo $?, proving cwd sync no longer overwrites the user's last shell status.

Fixes #3958
2026-07-01 02:27:05 +00:00
can1357 0fbcb63539 fix: preserved shells with running background jobs
- Added `Shell.liveBackgroundJobCount` to query active background processes.
- Retained per-call `:async:` shells if background jobs are still running upon turn completion.
- Reaped shells automatically once their last background process exits to prevent lingering processes.
2026-06-22 17:25:19 +02:00
roboomp e4ab780345 fix(tool): defaulted windows bash children to utf-8
Added Windows-only UTF-8 defaults for non-interactive bash child process environments when the inherited env does not already define encoding or locale values.

Added regression coverage for missing, inherited, per-command, and non-Windows env behavior.

Fixes #2701
2026-06-15 21:18:46 +00:00
can1357 ce4ebad726 feat(agent): added per-call tool concurrency resolver and parallel bash execution
- Extended `AgentTool.concurrency` to accept per-call resolver functions and resolved concurrency mode from each tool call, falling back to exclusive on resolver errors.
- Updated BashTool to schedule non-PTY calls as shared and PTY calls as exclusive so non-interactive bash calls can run in parallel within one message.
- Tracked in-use persistent shell sessions in the bash executor and routed overlapping calls on the same session key to isolated one-shot shells while preserving owner session availability.
2026-06-11 18:13:07 +02:00
handlecusion bbf8216768 fix(coding-agent): avoid interactive fish shortcuts 2026-06-10 16:36:09 +09:00
handlecusion 2d7d717029 fix(coding-agent): tighten user shell routing 2026-06-10 16:07:59 +09:00
handlecusion 8b9c4fa1b9 fix(coding-agent): respect user shell for shortcuts 2026-06-10 16:07:59 +09:00
David Andrews (LexGenius.ai) 3a73107cce fix(minimizer): address PR 2176 review feedback 2026-06-10 08:31:30 +02:00
David Andrews (LexGenius.ai) ce7ec45d42 feat(minimizer): deterministic shell-output minimizer on 15.10.8 2026-06-10 08:31:30 +02:00
can1357 a13e9827f4 fix(coding-agent): fixed bash output integrity, job lifecycle, and interception
artifact spill now includes the head-retained bytes (full capture was missing first ~20KB); chunk throttle coalesces instead of dropping; cd-prefix extraction defers shell-expanded paths; interceptor rule is quote-aware and catches clobber and variable targets; completed async jobs release their Shell; at job cap commands degrade to foreground; PTY mode drops the non-interactive env and notes silent downgrades; timeout/abort annotations always appended; removed dead idle-timeout-watchdog.
2026-06-10 01:27:17 +02:00
can1357 c069136eca refactor(exec): extracted eval-backends module and improved shell quarantine
- Moved EvalBackendsAllowance and related functions to a dedicated eval-backends.ts module.
- Replaced ad-hoc brokenShellSessions tracking with a quarantineShellSession helper that also awaits the abort cleanup promise.
- Applied quarantine on timeout and cancellation paths, not just errors.
2026-06-01 20:15:21 +02:00
can1357 47c70f6484 refactor(autoresearch): migrated executeProcess to use executeBash
- Replaced manual child_process.spawn logic with executeBash and TailBuffer.
- Added chunkThrottleMs option to executeBash for caller-controlled throttling.
- Removed inline killTree, stream management, and timeout/abort wiring.
2026-05-31 06:15:31 +02:00
can1357 3078d31a4c chore: reformat 2026-05-26 20:44:09 +02:00
can1357 1d8ee5a891 refactor(yield): migrated to scheduler.wait with abort support and gate
- Replaced Bun.sleep with scheduler.wait for Node-compatible cancellable sleeps.
- Added module-level timestamp gate to skip yields within 50ms of the last one.
- Threaded AbortSignal through ExponentialYield.sleep to cancel losing timers in race.
- Added tests covering gate behaviour and stray-timer cancellation.
2026-05-26 20:37:39 +02:00
hezhiyang2000 afe574b351 fix: prevent busy-wait in agent loop and bash executor
- yieldIfDue() uses compensated sleep (sleepAtLeast): retries Bun.sleep()
  until the requested wall-clock duration has elapsed. This is necessary
  because napi callbacks (uv_async_send) can wake the event loop
  prematurely, causing Bun.sleep(N) to return after only ~1-2ms.
- ExponentialYield for bash-executor: starts at 20ms, doubles to 10s.

Closes #1384
2026-05-26 17:35:00 +08:00
roboomp 23300d0348 fix(bash): quarantined stalled shell sessions
Quarantined persistent session keys only while the native cancellation promise remains unsettled, so healthy cleanup restores persistent mode and stalled cleanup cannot accumulate live shell instances.

Added coverage for both stalled and settled native cleanup paths.

Fixes #1347
2026-05-25 18:48:20 +00:00
roboomp 8e5c7c9bf1 fix(bash): kept persistent shells after cancel
Stopped marking persistent bash sessions as permanently broken when the JavaScript abort or timeout race wins.

Stopped the Rust descendant kill-wave helper once no cancellation targets remain so later commands are not swept into old cancels.

Fixes #1347
2026-05-25 18:40:22 +00:00
roboomp 14c7ddf7d0 fix(bash): returned on stalled cancellation
Raced bash execution against the JavaScript abort signal and timeout so the tool returns even when native shell cleanup does not settle.

Added regression coverage for native cleanup stalls on ESC abort and timeout.

Fixes #1347
2026-05-25 18:03:09 +00:00
can1357 2a1052ea9f fix(coding-agent): aligned output counters after sink replacement
- Adjusted OutputSink to disable head retention after replace(), resetting counters so later pushes append to the tail and do not trigger stale middle-elision in dump().
- Refined artifact link emission to insert a newline separator only when the minimized output lacked one.
- Added a regression test for replace-plus-push ordering that verifies no elision marker and aligned byte counts.
2026-05-15 14:46:54 +02:00
can1357 f1f6516056 refactor: reorganized exports and removed obsolete helper branches
- Removed export leakage by demoting many helper and const symbols to module-local scope.
- Renamed underscore-prefixed internals and cache fields, then updated related references and `satisfies never` checks.
- Deleted obsolete logic branches and helpers, including harmony-stream interruption flow and unused benchmark runtime helpers.
- Updated Biome config and manifests by broadening lint coverage and removing an unused `@napi-rs/cli` dev dependency.
- Adjusted tests and utilities to use renamed test helpers and remove redundant private test-only helpers/locals.
2026-05-14 04:36:19 +02:00
can1357 28b9ce7a0c feat(coding-agent): added middle-elision caps to OutputSink truncation
- Added `tools.artifactHeadBytes` and `tools.outputMaxColumns` settings with defaults in `SETTINGS_SCHEMA`.
- Expanded `OutputSink` with `headBytes`/`maxColumns` and middle truncate logic with elision markers and tracking.
- Updated output-meta to resolve sink settings, emit truncation metrics, and use `truncateMiddle` for spills.
- Integrated head and column limits into JS/Python/Bash/SSH/read output flows, with `:raw` skipping read truncation.
- Documented new output middle-elision and column-cap behavior in `CHANGELOG.md`.
- Added truncation tests for `OutputSink`, `truncateMiddle`, and read-tool line handling.
2026-05-13 11:19:11 +02:00
can1357 e3f7496deb feat(coding-agent): added ordered todo_write ops and sequential execution
- Changed `todo_write` to an ordered `op`-array model with `replace`, `start`, `done`, `rm`, `drop`, `append`.
- Removed legacy multi-field todo payloads and updated tests/fixtures to use ordered `{op, task?, phase?, items?}[]` args.
- Reworked todo operation execution to apply entries sequentially and validate missing or unknown task/phase IDs.
- Updated todo rendering to use `todo.content` only and changed bash artifact labels from `full result` to `raw output`.
2026-04-26 05:00:54 +02:00
can1357 033a4b704e fix(coding-agent/exec): adjusted minimized output artifact handling and footer text
- Guarded minimized output handling so the minimized text was only applied when it changed from the original output.
- Replaced the artifact footer text with a shorter `[full result: artifact://...]` marker when a minimized save artifact was created.
2026-04-26 01:22:22 +02:00
can1357 c61a5b9a56 feat(config): added minimizer output fields and compact shell summaries
- Added minimizer API fields (`MinimizerResult.text`, `settingsHash`) and shell options for minimized output behavior.
- Changed bash execution to print minimized text output and append artifact footers only after minimized output is saved.
- Added UTF-8-safe shell streaming with `on_chunk` callback routing and `replace()` output sink updates.
- Added core filter enhancements for git, cargo, go, and listing/python outputs to produce compact summaries.
- Added RTK command filters and fixtures to strip noise, truncate output, and normalize success fallbacks.
2026-04-24 11:13:43 +02:00
can1357 163eca4cb7 style: biome-format bash-executor jsdoc and minimizer sink line 2026-04-24 09:32:06 +02:00
can1357 084ffd2058 feat(cross-cutting): added shell minimizer planning from AST command parsing
- Added AST-based minimizer planning with brush-parser to classify commands before minimization.
- Added original text capture and byte-metric `minimized` telemetry to shell execution results.
- Added minimizer configuration controls, including trust-gated loading via `settingsHash` and limits.
- Added `onMinimizedSave` callback wiring to persist minimized outputs and annotate Bash sinks with artifact IDs.
2026-04-24 09:15:18 +02:00
can1357 4940961e01 feat: added shell minimizer settings and dispatch by program
- Added configurable minimizer settings to native and coding-agent APIs, including shellMinimizer options.
- Added minimizer execution plumbing through shell config, session-key generation, and buffered output capture.
- Added command identity detection and dispatching by program/subcommand with safe fallback to passthrough output.
- Added filter suites for git, docker, go, bun, cloud, and system commands to strip ANSI and compact noisy output.
- Added unit tests for detection and minimizer behavior across command support, failures, and passthrough paths.
2026-04-24 08:00:04 +02:00
can1357 9b78a6fa85 refactor(natives): migrated native bindings to NAPI-RS with auto-generated types
- Migrated native bindings from TypeScript wrappers to NAPI-RS generated modules with auto-generated type definitions and runtime enums.
- Replaced chunk tree API with stateful ChunkState class supporting render, edit, and resolve operations with improved error handling.
- Converted callback signatures to error-first pattern (error, result) for shell, PTY, glob, and grep operations.
- Introduced type-safe enums for MacOSAppearance, GrepOutputMode, KeyEventType, ImageFormat, and AstMatchStrictness replacing string literals.
- Refactored chunk tree implementation with dedicated modules for edit, indent, resolve, and state management with comprehensive validation.
- Moved clipboard utilities from native bindings to coding-agent package with improved OSC 52 and Termux compatibility.
2026-04-07 02:00:59 +02:00
luke 47dc03b835 fix: prevent TUI freeze on massive bash output and fix spinner rendering (#500)
- Sync OutputSink.push(): eliminate promise chain per chunk, buffer
  management and onChunk run inline, file writes deferred via queue
- 64KB native read buffer (was 4KB): reduces chunk count ~16x
- chunkThrottleMs in OutputSink: gate onChunk to every 50ms
- BashExecutionComponent streaming throttle: gate + 100-line cap
- Remove requestRender from chunk callbacks: spinner drives renders
- Remove double sanitization in appendOutput (already done by OutputSink)
- Inline SEGMENT_RESET in TUI doRender buffer writes: eliminates O(N)
  string allocations per frame from #applyLineResets
- Cache header Text in BashExecutionComponent (created once, reused)
- Gate sixel mask computation behind protocol + passthrough check
- Fix spinner: #spinnerFrame made optional, interval calls #updateDisplay
- Remove pendingChunks promise chains from bash-executor and bash-interactive
2026-03-21 16:05:42 +01:00
can1357 b5faa7d4be feat(coding-agent): added cursor navigation to message boundaries
- Added `moveCursorToMessageStart()` and `moveCursorToMessageEnd()` prompt actions for cursor navigation to message boundaries.
- Exposed editor methods for cursor movement to message start and end positions in InputController keybindings.
- Implemented message boundary navigation in Editor class with private helper methods for cursor positioning.
- Removed remote compaction settings test suite to align with feature deprecation.
2026-03-14 13:38:29 +01:00
can1357 ca2860b200 feat: added OpenAI compatibility config and 10 new AI models with reasoning support
- Added support for provider-level OpenAI compatibility configuration enabling reasoning effort mapping and streaming usage fallback across models.
- Added 10 new AI models (DeepSeek V3.2, Llama 3.1 405B, Mistral Large 3, Pixtral Large, and others) with updated pricing and context windows.
- Fixed autocomplete to preserve ./ prefix in relative file/directory path completions and paste marker expansion to handle regex tokens literally.
- Changed system prompt date format to ISO 8601 and tool download timeout from 15s to 120s for improved cross-platform compatibility.
- Refactored OpenAI completions provider to extract token parsing logic and support choice-level usage fallback with improved message serialization.
2026-03-14 13:38:29 +01:00