Commit Graph
760 Commits
Author SHA1 Message Date
can1357 98f6e9f004 chore: bump version to 16.3.6 2026-07-04 14:00:53 +02:00
can1357 959408f775 chore: reformat 2026-07-04 13:59:31 +02:00
can1357 81097c4ffa test(tui): consolidated streaming scrollback logic and testing infrastructure
- Exposed `Markdown.getLastRenderSettledRows` to track streaming progress.
- Simplified scrollback architecture by migrating logic to a unified `SeamLineList` boundary.
- Removed legacy safe-end methods and redundant `findCommittedPrefixResync` test suites.
- Fixed live tool and evaluation preview duplication issues during re-layouts.
2026-07-04 11:25:17 +02:00
can1357 cb30c981a0 feat(walker): implemented parallel filesystem traversal with streaming grep
- Introduced parallel streaming grep with windowed result processing to enhance search performance and memory management.
- Implemented stateful parallel file walking with buffer pooling and directory entry record caching to minimize memory allocations.
- Optimized ignore state derivation by using directory entry names instead of stat probes.
- Added comprehensive unit and performance tests covering parallel traversal correctness, early termination, and streaming behavior.
2026-07-04 11:22:04 +02:00
can1357 b258c790a5 style(pi-natives): fixed manual_assert lint in drop bomb test 2026-07-04 09:06:25 +02:00
can1357 db09905c25 refactor(pi-natives): reduced allocations in pattern deduplication
- normalize_pattern_list now skips all allocation for duplicate patterns
  and reuses the input String when trimming is a no-op.
2026-07-04 09:06:25 +02:00
can1357 1d7e20115b refactor(pi-iso): extracted shared command_failed error formatter
- Collapsed seven duplicated stderr-trim + exit-format sites across diff.rs, rcopy.rs, and overlayfs.rs into one pub(crate) helper.
- Exit code stays caller-formatted so signal-death renders unchanged.
- Also covers the fuse_mount site PR #4376 left with an eager to_string.
2026-07-04 09:06:25 +02:00
can1357 a3becdb7b6 Merge PR #4376: refactor(crates): clean up first-party Rust crates 2026-07-04 08:59:59 +02:00
can1357 fef9b62334 chore: bump version to 16.3.5 2026-07-04 05:19:15 +02:00
can1357 d0c1890a6c chore: bump version to 16.3.4 2026-07-03 06:37:14 +02:00
metaphorics 977e43f7f5 style(rust): format cleanup changes
Formats Rust files touched by the cleanup commits after cherry-picking them onto current upstream/main.

Op: compress
2026-07-03 09:31:52 +09:00
metaphorics cb80aaa6fb refactor(pi-walker): behavior-preserving cleanup\n\nOp: compress 2026-07-03 09:31:43 +09:00
metaphorics 17d9ab3b24 refactor(pi_uu_grep): behavior-preserving cleanup\n\nOp: compress 2026-07-03 09:31:43 +09:00
metaphorics 6680312a25 refactor(pi-shell): behavior-preserving cleanup\n\nOp: compress 2026-07-03 09:31:43 +09:00
metaphorics c458b60c8b refactor(pi-natives): behavior-preserving cleanup
Op: compress
2026-07-03 09:31:43 +09:00
metaphorics c79064ba62 refactor(pi-iso): behavior-preserving cleanup\n\nOp: compress 2026-07-03 09:31:43 +09:00
metaphorics 9e8f115d4f refactor(pi-ast): behavior-preserving cleanup\n\nOp: compress 2026-07-03 09:31:43 +09:00
can1357 afc79e4cda chore: bump version to 16.3.3 2026-07-03 00:57:22 +02:00
can1357 016a096611 Merge remote-tracking branch 'origin/farm/43148a2d/fix-git-apply-stderr-deadlock' 2026-07-02 23:43:11 +02:00
can1357 9e0b6cddf2 chore: bump version to 16.3.2 2026-07-02 17:50:38 +02:00
roboomp 2335c717a6 fix(pi-iso): drained git apply stderr during patch writes
Spawned a stderr reader before writing git apply stdin so large diagnostics cannot fill the pipe and deadlock dirty-state seeding.

Added a regression test with a fake git process that fills stderr before consuming stdin.

Fixes #4231
2026-07-02 08:34:23 +00:00
can1357 0ea6ea630b chore: bump version to 16.3.1 2026-07-02 09:00:04 +02:00
can1357 36cfb54e92 chore: bump version to 16.3.0 2026-07-02 04:12:21 +02:00
can1357 ec69edad5d refactor(natives): enabled disk logging for background task panics
- Downgraded `blocking_task_panic_scope` panics from silent to logged recoverable.
- Persists panic reports of caught worker task panics to the disk crash log while keeping stderr silent.
- Consolidated panic payload message extraction by reusing `crash_handler::panic_payload` in the task runner.
- Promoted the `SilenceHook` test helper to the shared testing module for use across multiple test suites.
2026-07-02 02:40:07 +02:00
can1357 ba1bd690e0 fix(natives): survived panic payloads whose destructors panic
- Extracted the panic message before disposing the payload; disposal now runs under its own catch_unwind with mem::forget fallback so a Drop-panicking panic_any payload can no longer unwind across the napi extern C boundary and abort the host.
2026-07-02 00:32:48 +02:00
can1357 3c22d25200 Merge PR #4110: fix(natives): catch task::blocking panics before FFI to reject JS Promise (@roboomp) 2026-07-01 21:53:15 +02:00
can1357 826517dc69 Merge PR #3969: fix: preserve bash cwd without hidden pwd probe (@jeffscottward) 2026-07-01 21:50:54 +02:00
can1357 e4fff0b061 fix(natives): probe reserved rayon capacity 2026-07-01 21:42:25 +02:00
can1357 d1015a6b87 Merge PR #3774: fix(natives): cap rayon pool on Windows (@roboomp) 2026-07-01 21:42:25 +02:00
can1357 5356713eae chore: bump version to 16.2.13 2026-07-01 20:03:42 +02:00
roboomp 3c698d136e test(natives): serialized panic-hook mutations behind a shared mutex
Introduced crate::testing::lock_panic_hook, a process-global Mutex that
every hook-mutating test now holds across its entire take -> set -> run
-> restore window. Without it, two parallel tests in the default cargo
test harness could interleave their take_hook / set_hook calls and pin
the noop hook as the process-global default, silently muting crash
diagnostics for every later test in the crate.

SilenceHook in task tests and blocking_task_panic_scope_restores_after_unwind
in crash_handler tests both acquire the lock on entry; SilenceHook keeps
the guard as a field so the hook restore in Drop happens under the same
lock. Mutex poisoning is unwrapped to inner so a single failing test
does not cascade.

Fixes #4071
2026-07-01 07:17:02 +00:00
roboomp 5662cc73df fix(natives): suppressed crash reports for caught task panics
Blocking task panics are now wrapped in a thread-local crash-handler scope before catch_unwind executes the worker closure. The panic hook recognizes that scope and treats the panic as silently recoverable, so it does not write a native crash report or chain to the default hook before the panic is converted into a GenericFailure Promise rejection.

The existing uutils recoverable path keeps its log-only behavior. Added crash-handler tests for the silent disposition and unwind-safe scope teardown.

Fixes #4071
2026-07-01 07:12:45 +00:00
roboomp bbd4c66768 fix(natives): catch task::blocking panics before FFI to reject Promise
napi-rs 3.9.4 registers async-work `execute` at src/async_work.rs:109 as
a plain `unsafe extern "C" fn` — not `extern "C-unwind"`. Any panic
inside a `Blocking::compute` closure unwound past that boundary and
force-aborted the host process under Rust's stabilized C-unwind rules
(RFC 2945, stable since 1.81), losing the JS Promise and session state.

Wrap the user closure in `std::panic::catch_unwind` inside
`Blocking::compute` and map the panic payload to
`Error::new(Status::GenericFailure, ...)` so it flows through napi-rs's
existing rejection path (`inner_task.reject` in `complete_impl`) and
surfaces as a rejected JS Promise instead of a host abort. Every
`task::blocking` caller (grep, ast, glob, listWorkspace, html-to-markdown,
snapcompact, fuzzy find, clipboard image read) inherits the guard.

Correct the root Cargo.toml `panic = "unwind"` comment — napi-rs's
per-call `catch_unwind` only covers the tokio-future path, not the
`Task`/`AsyncTask` async-work path we use here.

Regression test in `crates/pi-natives/src/task.rs` synchronously invokes
`Blocking::compute` with panicking closures (str literal, formatted,
`panic_any`, plus Ok/Err/double-invoke controls) and asserts the returned
`napi::Error` carries the tag and payload — proving the invariant: a
panicking closure MUST NOT unwind past this method.

Fixes #4071
2026-07-01 07:03:23 +00:00
Jeff Scott Ward 3da25618ea fix: preserve bash cwd without pwd probe 2026-06-30 23:51:28 -04:00
can1357 fccc0ed3ce chore: bump version to 16.2.12 2026-07-01 05:29:19 +02:00
can1357 db8c79cc93 style: apply formatter and fix devin test enum
biome + cargo fmt over merge-sweep eval-fix commits; correct StopReason.END_TURN (nonexistent) to StopReason.FUNCTION_CALL in devin streaming test
2026-07-01 04:45:28 +02:00
can1357 8cc7520e47 merge PR #3954: fix(pi-shell): wired fd directory walk to observe scope cancellation 2026-07-01 04:40:39 +02: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
roboomp c303da9c62 test(pi-shell): tightened fd cancel-heartbeat coverage per PR #3954 review
The two search()-level cancel tests (`fallback_walk_observes_cancel_flag`
/ `fast_walk_observes_cancel_flag`) pre-set the cancel flag before
invoking search(), but search() and try_search_fast each have a
pre-loop guard that breaks out on cancelled before either walker call
is invoked. That means both tests still pass with the walker call
sites reverted to no-op heartbeats, so they don't defend the fix.

Replace them with symmetric walker-level tests that drive the two
walker APIs fd uses:

- `cancel_heartbeat_aborts_collect_with_heartbeat` — the fallback
  path's `collect_with_heartbeat` call; asserts WalkError::Interrupted
  (was `cancel_heartbeat_aborts_walker_when_flag_is_set`, renamed for
  API-specific clarity and given a filler-file seed so the outcome
  shows a real drain on regression).
- `cancel_heartbeat_aborts_for_each_entry_with_heartbeat` — the fast
  path's streaming API; asserts WalkError::Interrupted AND that the
  visitor never received any entry.

Both fail against the pre-fix no-op heartbeat with WalkStatus::Complete
/ a fully drained WalkOutcome. Keep
`walk_completes_normally_when_cancel_flag_is_unset` as the positive
regression pin — that path does exercise search() end to end because
the outer guard passes with cancelled=false.
2026-07-01 01:18:41 +00:00
roboomp 3bb2ade643 fix(pi-shell): wired fd directory walk to observe scope cancellation
The in-process fd builtin passed no-op heartbeats to pi_walker for
both its gitignore-respecting fallback path (`collect_with_heartbeat`
in `search`) and its fast path (`for_each_entry_with_heartbeat` in
`try_search_fast`), so cancellation of a large or slow directory walk
was deferred until traversal completed. The shell wrapper flips the
shared `AtomicBool` cancel flag when the runtime cancellation token
fires and then awaits the blocking task; with no heartbeat hookup the
walker had no way to observe the flag mid-walk and kept collecting the
whole tree before the wrapper could return exit 130.

Introduce `cancel_heartbeat(&AtomicBool)` — the walker-level heartbeat
that returns `io::ErrorKind::Interrupted` when the flag is set — and
plug it into both walker calls. Both call sites recognize the resulting
`WalkError::Interrupted` alongside `cancelled` and break silently
instead of surfacing an `fd:` diagnostic on stderr; the shell wrapper
owns the user-visible exit code.

Regression cover: a walker-level test pre-sets the cancel flag and
asserts `collect_with_heartbeat(cancel_heartbeat(&flag))` surfaces
`WalkError::Interrupted` instead of collecting the tree; two
higher-level `search` tests exercise the silent break for both the
fallback and fast paths; a fourth pins the non-cancelled contract so
the added heartbeat can't stall normal searches. Neuter the helper to
a no-op and the walker-level test fails with the pre-fix `WalkOutcome`
showing every entry scanned — the exact bug the issue reports.

Fixes #3949
2026-07-01 01:08:48 +00:00
can1357 b2a859a7c5 chore: bump version to 16.2.11 2026-07-01 03:06:34 +02:00
can1357 2e8c012eec Merge remote-tracking branch 'origin/farm/3cd77781/bound-ast-search-pages' 2026-07-01 02:57:36 +02:00
can1357 6e9ae7adc7 Merge remote-tracking branch 'origin/farm/a032fc7d/grep-rg-walker-cancel-heartbeat' 2026-07-01 02:57:24 +02:00
can1357 266dca118f refactor(pi-walker): made file type conversion helper functions const
- Converted `file_type_from_dtype` and `file_type_from_mode` into const functions.
- Removed the unused `OsStringExt` import.
2026-07-01 02:56:16 +02:00
roboomp 12b25eb349 fix(ast): materialized retained match text at retention time
Previously each retained match cloned an Arc to the whole source, keeping large generated/vendor files alive until the scan finished. Now the retained heap stores just the per-match matched text, so the retained payload stays bounded to the small span even when a broad page window keeps a few matches from very large files.

Refs #3935
2026-07-01 00:25:50 +00:00
roboomp f40214032a style: bun run fix 2026-06-30 23:54:23 +00:00
roboomp 578a2d7626 fix(ast): bounded ast search pagination payloads
Retained only the requested AST search page window in native ast_grep/ast_match and the coding-agent multi-target wrapper while preserving exact totals.

Fixes #3935
2026-06-30 23:54:17 +00:00
roboomp 6440adebf0 fix(uutils): surfaced rg files cancellation to caller
rg --files used collect_filtered_files for directory operands. When a
walker heartbeat observed the uutils cancellation flag, the helper
returned Ok(Vec::new()), making the caller treat the aborted walk like an
empty directory.

Return an error for cancelled collection and let rg --files / sorted rg
callers map it to a silent had-error outcome, stopping later operands
without writing post-cancel output.

Fixes #3933
2026-06-30 23:50:54 +00:00
roboomp 16ef314e9c fix(uutils): stopped grep rg operands after cancellation
Recursive grep and rg already stopped the active directory walk when the
uutils scope cancel flag was observed, but the outer operand loop could
still continue into later regular-file operands before the shell wrapper
returned 130.

Stop subsequent grep, rg, and rg --files operands once cancellation is
set. Extend the cancellation regressions with a later regular-file
operand so the tests cover the exact post-directory continuation case.

Fixes #3933
2026-06-30 23:47:34 +00:00
roboomp dbab0ef84d fix(uutils): wired grep/rg directory walks to observe scope cancellation
The grep and rg in-process builtins passed no-op heartbeats to pi_walker
when recursing into a directory, so the uutils scope's cancel flag was
ignored mid-walk. The shell wrapper sets that flag on abort/timeout and
then awaits the blocking task — with no heartbeat hookup, a cancelled
recursive grep/rg waited for the whole tree to be scanned before the
shell could return exit 130.

Add pi_uutils_ctx::is_cancelled() and have grep's search_dir, rg's
search_dir, and rg's collect_filtered_files supply heartbeats that
return io::ErrorKind::Interrupted when the flag is set. The walker maps
that to WalkError::Interrupted, which the utilities now silently treat
as a harness cancellation (no spurious 'native directory scan
interrupted' on the command's stderr — the shell wrapper owns the
user-visible exit code).

Regression tests pre-set the cancel flag and assert grep -r /
rg / rg --files exit without scanning the matching file in the tree.

Fixes #3933
2026-06-30 23:37:20 +00:00