Commit Graph
796 Commits
Author SHA1 Message Date
can1357 b2467ecc16 fix-tui-image-budget-suppressed-key-eviction 2026-07-05 13:25:25 +02:00
can1357 757f573773 Merge PR #4279: fix(tui): evict purged image keys from ImageBudget key map (@metaphorics) 2026-07-05 13:25:25 +02:00
can1357 ad52366f7f Merge PR #4449: fix(tui): emit BEL under Zellij so notifications flag backgrounded panes (@mattwilkinsonn) 2026-07-05 13:10:25 +02:00
roboomp 1fcdc4f882 fix(tui): preserved autocomplete for no-arg slash prompts
- Propagated builtin allowArgs metadata into TUI autocomplete entries.

- Let no-arg slash-looking prompts fall through to prompt-composer completions while keeping argument-capable commands scoped.

- Added regressions for /settings @ and /settings #copy.
2026-07-05 09:05:45 +00:00
roboomp ed63b62889 fix(tui): scoped autocomplete to slash command arguments
- Stopped prompt-composer # actions and @ file references from claiming submitted slash-command argument text without explicit argument completions.

- Added provider regression tests for /rename title arguments and explicit command argument completions.

Fixes #4600
2026-07-05 08:52:32 +00:00
can1357 ada50effa8 feat(tui): implemented visual-record scrollback with exact zone tracking
- Migrated native scrollback logic to a visual-record model with a three-zone row verification system.
- Replaced heuristic-based audit boundaries with exactness-boundary tracking for improved reliability.
- Resolved issues with live tool preview duplication and content vanishing during scroll.
- Added adaptive index re-basing for frame shrinks and audit exemptions for frozen visual snapshots.
2026-07-04 12:13:34 +02:00
can1357 d5e9084e65 refactor: restructured audit logic and render boundary tracking
- Removed complex snapshot caching and volatile/stable state tracking logic.
- Replaced multi-zone audit logic with streamlined tail-sample checks.
- Simplified render boundaries by deriving a single final boundary from the live region.
- Eliminated redundant audit state management and auxiliary safe-end interfaces.
2026-07-04 09:50:20 +02:00
can1357 21d2c2271a Revert "fix(tui): merged scrollback offer boundary repair"
This reverts commit ae89b3ff08, reversing
changes made to 227874dcc6.
2026-07-04 05:12:18 +02:00
Matt Wilkinson 66e3ef6c82 fix(tui): emit BEL under Zellij so notifications flag backgrounded panes
sendNotification only appended a BEL inside tmux, so under Zellij an OSC
9/99 notification was dropped (Zellij doesn't forward it and has no DCS
passthrough) and a backgrounded pane got no attention indicator. Added
isInsideZellij() and a Zellij branch that follows the OSC with a bare BEL,
raising Zellij's [!] flag like tmux's monitor-bell.

Refs can1357/oh-my-pi#3583
2026-07-03 09:21:52 -04:00
roboomp 30527aee0c fix(tui): cut TUI CPU overhead during interactive sessions
Four tightly-scoped hot-path fixes covering the highest-impact items in the
reporter's CPU profile (13.1 s profiled / 30 s window):

1. `event-controller.ts:handleEvent` no longer fires a blanket
   `statusLine.invalidate() + ui.requestRender()` before every session event.
   The pre-render was a leftover from #4145 when `updateEditorTopBorder()`
   still eagerly rebuilt the border; the lazy provider added in #4145 made
   it redundant. It fired on every `message_update`/`tool_execution_update`
   during streaming — the pre-render's frame ran while the handler was
   awaiting, then the handler's own `requestRender` scheduled a second
   identical frame. Every handler that mutates visible state already calls
   `requestRender()`.

2. `shimmer.ts:shimmerSegments` iterates the segment string in place instead
   of building a code-point array with `Array.from(seg.text)` every animation
   frame. Runs of same-tier chars are emitted via a single `slice` per run
   rather than accumulating into `runBuf`. Surrogate pairs stay atomic — the
   code-point index still advances by 1 per emoji. Microbench over 30k
   frames: 45 ms → 18 ms (2.53x), allocation rate down from ~N-per-frame to
   a handful per frame. New tests cover mixed BMP+surrogate and all-emoji
   inputs. `Array.from` was the #1 self-time hotspot in the reporter's
   profile at 10.2%.

3. `Markdown.setText` gains an equality guard mirroring `Text.setText`
   (returns `false` when `text === #text`). Providers re-emit identical text
   on ticks with no delta (throttled frames, reconciled tool-execution
   updates); each of those now short-circuits instead of dropping
   `#cachedLines` and forcing a full lex + wrap on the accumulated paragraph
   (the reporter's #3 hotspot at 8.4%). New test asserts render-reference
   stability + return-value semantics.

4. `SPINNER_RENDER_INTERVAL_MS` aligned with `SPINNER_GLYPH_ADVANCE_MS`
   (both 80 ms). The previous 33 ms cadence emitted ~2.4 paints per glyph
   step; the differential-output dedup only skips the write, not the
   compose walk. Visually identical (glyph advance was already 12.5fps),
   halves paints during tool execution.

Skipped (out of scope for a bug fix, deserve dedicated PRs):
- Freezing streaming prefix on single `\n` boundaries — correctness-bound
  to `\n\n` block separators (CommonMark loose-list continuation).
- Compose-phase idle gate + adaptive-backpressure moving-average — need a
  component-level dirty flag; the 200 ms cap in `#scheduleRender` was set
  for a reason (#4145 tail-latency guard).

Tests updated: two IRC-expiry tests in event-controller-message-start.test.ts
that were asserting the pre-render's second `requestRender` call now expect
one.

Fixes #4353
2026-07-02 22:11:26 +00:00
can1357 ab75b1b7d1 fix(tui): guarded autocomplete suffix acceptance 2026-07-02 23:51:18 +02:00
can1357 26845af593 Merge remote-tracking branch 'origin/farm/b0af008e/cancel-autocomplete-on-destructive-edit' 2026-07-02 23:43:09 +02:00
can1357 ae89b3ff08 fix(tui): merged scrollback offer boundary repair
Merged PR #4330 and fixed the remaining offered-boundary regression by stopping offer promotion at intervening live blocks.

Verified with targeted transcript/native scrollback regressions: 40 pass.
2026-07-02 23:41:53 +02:00
roboomp 6ed19b5dbe fix(tui): promoted forced-overflow rows into offer zone
Extended the audited-offer classification to cover rows already committed as forced-overflow when the offer boundary rises to include them, and widened the committed-prefix hard scan to the offer boundary so a single-row shift inside the offered zone catches instead of being tolerated by the tail sample.

Added regression asserting the offer boundary appearing after prior overflow still repairs the shifted tail on the next live growth.

Addresses codex-connector review on #4330.
2026-07-02 16:37:45 +00:00
roboomp 49b4ef50f8 fix(tui): fixed audited scrollback tail rows
Separated audited offerable transcript rows from durable snapshot rows so lower finalized content below a live block can be repaired instead of duplicated when the live block grows.

Added transcript and virtual-terminal regressions for the lower finalized tail case.

Fixes #4326
2026-07-02 16:24:11 +00:00
roboomp d71f252cd3 fix(tui): treated ssh connection as remote
Covered SSH_CONNECTION-only sessions when skipping modifyOtherKeys for unknown SSH terminals.
2026-07-02 16:20:44 +00:00
roboomp 66e17bce71 fix(tui): skipped unsafe ssh keyboard fallback
Skipped the xterm modifyOtherKeys fallback for unknown SSH terminals so iOS SSH clients do not lose Shift input while preserving the fallback for known/local terminals.

Fixes #4325
2026-07-02 16:15:50 +00:00
roboomp 6037912835 fix(tui): invalidated autocomplete on destructive edits and guarded stale Tab/Enter acceptance
- Route #deleteToStartOfLine, #deleteToEndOfLine, #deleteWordBackwards,
  #deleteWordForwards, and #insertTextAtCursor through
  #retriggerAutocompleteAtCursor so text-mutating keys (Ctrl+W, Ctrl+U,
  Ctrl+K, Alt+Backspace, Alt+D) and paste/yank refresh the popup like
  #handleBackspace / #handleForwardDelete already do.
- Add the staleness guard to the Tab and Enter+file-path acceptance
  paths in Editor.handleInput; the Enter+slash path already had it.
- Tighten #autocompletePrefixMatchesCursorText to mirror
  CombinedAutocompleteProvider.applyCompletion's re-anchor branches
  (exact / path-suffix / clean leading-slash / @-token) so genuine
  "extended prefix" cases stay valid while destructive edits and
  paste-over-prefix scenarios are correctly rejected.

Adds regression tests exercising every destructive keybinding, yank
over the prefix, and the Enter+file-path fall-through to submission.

Fixes #4295
2026-07-02 10:16:52 +00:00
metaphorics 61e166921a fix(tui): evict purged image keys from ImageBudget key map
ImageBudget#acquireId stored every non-empty imageKey in #keyToId (packages/tui/src/components/image.ts:134) but never removed entries, so the map grew unbounded for the lifetime of the TUI session. endPass now deletes the #keyToId entry for each id as it is demoted/purged from live graphics (packages/tui/src/components/image.ts:188-193), and takeAllTransmittedIds clears the map on the full transmitted-reset path (packages/tui/src/components/image.ts:223). Added unit tests covering demotion eviction and full reset. Verification (bun run check:types and bun test test/image-budget.test.ts) was not executed per campaign constraints.

Closes #4250
2026-07-02 17:30:30 +09:00
can1357 5dcf2ad197 chore: cleanup 2026-07-02 03:08:16 +02:00
can1357 dbe232f643 refactor(tui): optimized render pipeline allocations and simplified input parsing
- Bypasses frame array allocation and merging during render except when hosted under ConPTY.
- Reuses the active window array slice for DECCARA calculations to avoid redundant array copies.
- Simplifies the `stdin-buffer` CSI sequence scanner by removing unnecessary resume search logic and redundant SGR mouse validation regexes.
2026-07-02 02:40:08 +02:00
can1357 e8a8c2402c fix(coding-agent): prevented asynchronous write races in plan reviews
- Ensures in-memory overlay edits are durably written to the plan file before proceeding with approval.
- Avoids asynchronous write races by awaiting the final plan file serialization.
- Aligns synthetic approved-plan prompts with reference-only expectations.
2026-07-02 02:19:26 +02:00
can1357 507328af36 fix(tui): implemented in-place viewport rewrites during overlay scrolling
- Rewrites viewport in-place rather than shifting native history when window position moves while overlays are visible.
- Prevents scrolling native terminal history during frozen commit tape states.
- Re-baselines terminal cursor safely to the top row using viewport-clamped cursor up sequences during virtual scroll rewrites.
- Syncs the internal window tracking row state and commits the redrawn frame on virtual scroll rewrites.
2026-07-02 02:18:54 +02:00
can1357 d4182835dc fix(tui): bounded escape sequence scanning to chunk limits
- Replaced unbounded `String#indexOf` lookups with structured byte loops to enforce `MAX_STRING_SEQ_BYTES` cap.
- Stopped unterminated OSC, DCS, and APC sequences from scanning past their limits and blocking the event loop.
- Maintained a one-byte overlap when checking chunk boundaries to ensure split escape terminators are correctly reassembled.
- Added comprehensive unit tests covering split boundary terminators and oversized payload scenarios.
2026-07-02 01:51:09 +02:00
can1357 5f1ed0fcde chore: reformat 2026-07-01 23:14:36 +02:00
can1357 5c38d3ccce Merge PR #2141 (semantic port): bound ConPTY full-paint frames (@roboomp)
Fixes issue #2115: ConPTY hosts truncated a >1MB single full paint at a logical-line boundary, corrupting large-session resume. Bounds the bytes #emitFullPaint emits (retain tail) while keeping full logical state for render planning/commit; guarded to ConPTY hosts only. Includes the issue-2115 repro test. The PR head's original pre-planning truncation was obsolete against the refactored render pipeline, so the evaluator-approved approach (fix 44b88a2f5) was ported onto current #emitFullPaint.
2026-07-01 22:45:43 +02:00
can1357 ab7f623ac4 Merge PR #4149: fix(tui): coalesce editor top-border rebuild to render tempo (#4145) (@roboomp) 2026-07-01 21:53:18 +02:00
can1357 cfdd369d9b fix(tui): reset stdin escape hint before paste 2026-07-01 21:53:17 +02:00
can1357 6022239102 Merge PR #4122: fix(tui): bound terminal input parsing so malformed sequences and non-bracketed pastes do not block the event loop (@roboomp) 2026-07-01 21:53:17 +02:00
can1357 87a9b9e98e Merge PR #3891: fix(coding-agent): replay scrollback on theme changes (@lederniermagicien) 2026-07-01 21:50:53 +02:00
can1357 8fd35c4324 Merge PR #3862: perf: cut edit-pipeline and session-branch hot-path complexity (@oldschoola) 2026-07-01 21:47:55 +02:00
can1357 9a49549d62 Merge PR #3828: perf(tui): memoize fuzzy search index + prepare query once per filter (@oldschoola)
# Conflicts:
#	packages/tui/test/fuzzy.test.ts
2026-07-01 21:44:15 +02:00
roboomp 809a8a348d fix(tui): coalesce editor top-border rebuild to render tempo
EventController.handleEvent rebuilt the editor's status-line top border
synchronously on every session event via updateEditorTopBorder(). During
a long-running eval that fires 5-10 events/s, each rebuild ran
StatusLine.getTopBorder → #buildSegmentContext → getCachedContextBreakdown
→ session.getContextUsage → estimateTokens (with JSON.stringify per
toolCall block) — the render pipeline is throttled to ~30 fps, so most
rebuilds were dropped before painting. Combined with a scheduler that
collapsed cadenceDelay to zero whenever a frame overran the 33ms budget,
the TUI busy-looped at ~40-50% CPU.

Fix:
- Editor gains setTopBorderProvider(): a lazy builder invoked once per
  editor render. InteractiveMode installs it in the constructor and on
  setEditorComponent, so the rebuild coalesces to the render tempo
  regardless of event rate.
- Delete updateEditorTopBorder wrapper (now equivalent to
  ui.requestRender) and inline every call site.
- Add adaptive render backpressure: a frame that exceeds
  MIN_RENDER_INTERVAL_MS inflates the next scheduling delay to
  2 * last_frame_cost, capped at 200 ms, targeting a 50% render duty
  cycle instead of pinning the CPU at t=0.

New regression tests:
- editor-top-border-provider.test.ts: provider fires exactly once per
  render, wins over eager setTopBorder, falls back when cleared, gets
  the correct availableWidth.
- adaptive-render-backpressure.test.ts: cheap frames keep the 33 ms
  cadence, a slow frame idles proportionally, pathological frames are
  capped at 200 ms.

Verified with bun test packages/tui/test (all 246 relevant tests pass)
and bun test packages/coding-agent/test/modes (455 tests pass). Three
pre-existing agent-session-handoff snapcompact failures on main are
unrelated (snapcompactSupportedChars binding).

Fixes #4145
2026-07-01 13:51:43 +00:00
roboomp 089db21333 fix(tui): bound terminal input parsing so malformed sequences and non-bracketed pastes do not block the event loop
Three failure modes shared the same root cause on the StdinBuffer.process
hot path — unbounded synchronous work in a single call.

- `StdinBuffer.extractCompleteSequences` grew each escape candidate one code
  unit at a time and re-tested every prefix, so a malformed CSI/OSC/DCS/APC
  streamed across chunks re-inspected the accumulated buffer on every
  `process()` call (issue A). Replaced the grow-and-recheck loop with a
  single linear scan bounded by a per-type cap (CSI 4 KiB, OSC/DCS/APC 16
  MiB) and a resume-search offset carried on `StdinBuffer` so a legit
  chunked OSC 5522 image paste stays O(total) instead of O(total²).
- `BracketedPasteHandler` had no cap or timeout: a caller that bypassed
  StdinBuffer (fed the start marker with no end marker) grew `#buffer`
  forever (issue B, defense in depth). Added an optional `byteLimit` option
  (default 64 MiB) that aborts paste mode and delivers accumulated bytes as
  `pasteContent`, mirroring `StdinBuffer#abortPaste`.
- The `ProcessTerminal` data handler ran six always-executed escape-probe
  regex tests per `data` event; a 100 KB non-bracketed paste (terminal
  without DEC 2004 support) turned into ~600K regex executions (issue C).
  Added a fast path that forwards non-ESC sequences straight to the input
  handler when no reassembly buffer is holding state.

Verified with new stdin-buffer + bracketed-paste tests plus empirical
repros: a streamed 1 MiB malformed CSI drops from ~4300 ms to ~50 ms of
synchronous work, and a 1 MiB chunked OSC 5522 payload drops from ~6800 ms
to ~25 ms.

Fixes #4073
2026-07-01 07:19:28 +00:00
roboomp 31794df6dc fix(tui): preserved unicode fuzzy search terms
- Preserved Unicode letters, marks, and numbers during fuzzy-search normalization so CJK and other non-ASCII queries no longer collapse to match-all searches.
- Added regression coverage for Chinese fuzzy filtering against unrelated ASCII items.

Fixes #4114
2026-07-01 07:15:03 +00:00
roboompandcan1357 3822a83b46 fix(tui): cleared stale streaming prefix caches
Cleared frozen-prefix render state after full-lex renders cannot establish a current appendable prefix, preventing truncated transient text from reusing spacer lines produced with a former tail.

Added regression coverage for truncating back to a previously frozen prefix.

Fixes #3975
2026-07-01 05:31:53 +02:00
roboomp 7054265483 fix(tui): cached streaming markdown prefix renders
Reused rendered frozen-prefix lines during transient Markdown renders so streaming assistant updates avoid re-rendering stable code blocks and other completed blocks.

Added focused regression coverage for prefix reuse and cache advancement across newly frozen blocks.

Fixes #3975
2026-07-01 02:46:36 +00:00
can1357 f7df67ad72 Merge remote-tracking branch 'origin/farm/df125a92/fix-skill-slash-replace-prompt' 2026-06-30 20:17:24 +02:00
roboomp 095392d144 fix(tui,coding-agent): preserved draft when accepting mid-prompt /skill: autocomplete
The mid-prompt slash skill autocomplete added in #3654 replaced the
entire editor draft with /skill:<name> on accept so the dispatcher
(which only matched leading /skill:) would still fire. That wiped
every keystroke the user had typed before reaching for the skill.

Insert the /skill:<name> token at the cursor in the TUI editor —
replacing only the partial /sk slash token, leaving prose before and
after intact — and extend the skill-command parser so a /skill:<name>
token surrounded by whitespace is recognized as an invocation too,
with the surrounding prose threaded through to the skill as args.

The parser change is shared across all three dispatch sites
(interactive TUI, ACP, RPC) via a new parseSkillInvocation helper
in extensibility/skills, so the three Map<string,string> /
session.skills lookups stay aligned on the same parse.

Fixes #3913
2026-06-30 16:12:53 +00:00
can1357 5cc84db4c4 feat(tui): enabled programmatic form submission via editor APIs
- Added a public `submit()` method to the `Editor` class to trigger form submission.
- Updated the `EditorComponent` interface to expose an optional `submit()` method.
2026-06-30 16:16:39 +02:00
Magicien 7da80bc325 fix(coding-agent): replay scrollback on theme changes 2026-06-30 13:06:53 +01:00
roboomp c2d6c8cf18 fix(tui): deliver buffered double-Esc as two events and re-arm loader after task completion
StdinBuffer held a bare `\x1b\x1b` chunk and timer-flushed it as one
sequence. `parseKey("\x1b\x1b")` returns undefined, so CustomEditor
fell through to the base editor and never fired the configured `onEscape` —
the double-escape gesture and the second-press single-Esc handler both went
dead whenever the terminal batched the two presses into one stdin read.

Split an exact bare `\x1b\x1b` into two ESC events only after the
flush window proves no follower arrived. If a follower does arrive, emit the
first ESC and restart parsing at the second ESC so legacy Alt chords
(`\x1bd`, `\x1b\x7f`) remain one downstream keypress. Meta-CSI/SS3
chords (`\x1b\x1b[A`, `\x1b\x1bO…`) still emit as one combined
sequence.

EventController.tool_execution_update re-armed the working loader when a
transient overlay (auto-compaction / auto-retry / handoff) had torn it down
mid-tool; tool_execution_end did not. A subagent (`task`) call only fires
_end, so a task result landing after such an overlay left the UI looking
idle even though the session was still streaming. Mirror the reconciler
call in #handleToolExecutionEnd.

Fixes #3857
2026-06-30 04:30:42 +00:00
oldschoola d9bc5ca405 perf: cut edit-pipeline and session-branch hot-path complexity
Four non-overlapping algorithmic complexity reductions in hot paths.
(Streaming-reveal throughput is owned separately by #3843.)

1. session/session-manager.ts pathTo: O(n^2) branch.unshift() leaf->root
   walk -> O(n) push + single reverse(). Hot path (5-10x/turn via getBranch).

2. edit/streaming.ts extractAddedLines: O(n^2) progressive string
   concat per streaming tick -> array push + single join.

3. edit/modes/patch.ts: collapseConsecutiveSharedLines O(n*m) filter
   + includes -> Set (O(n+m)); collapseRepeatedBlocks O(n^3) with
   per-iteration slice allocations + every() -> index arithmetic with
   a single shared.has() guard. Semantics preserved.

Honorable: tui/src/utils.ts replaceTabs reallocated
" ".repeat(DEFAULT_TAB_WIDTH) every call -> hoisted TAB_SPACES const.
2026-06-29 21:23:42 -07:00
roboomp 64734021a7 fix(tui): deliver buffered double-Esc as two events and re-arm loader after task completion
StdinBuffer held a bare `\x1b\x1b` chunk (or emitted it as one when followed by
a non-CSI byte). `parseKey("\x1b\x1b")` returns undefined, so CustomEditor
fell through to the base editor and never fired the configured `onEscape` —
the double-escape gesture and the second-press single-Esc handler both went
dead whenever the terminal batched the two presses into one stdin read.

Split a bare `\x1b\x1b` into two ESC events at the buffer layer, mirroring
the existing split for ESC + SGR mouse report. Meta-CSI/SS3 chords
(`\x1b\x1b[A`, `\x1b\x1bO…`) still emit as one combined sequence.

EventController.tool_execution_update re-armed the working loader when a
transient overlay (auto-compaction / auto-retry / handoff) had torn it down
mid-tool; tool_execution_end did not. A subagent (`task`) call only fires
_end, so a task result landing after such an overlay left the UI looking
idle even though the session was still streaming. Mirror the reconciler
call in #handleToolExecutionEnd.

Fixes #3857
2026-06-30 03:41:24 +00:00
oldschoola 56b2753b64 perf(tui): memoize fuzzy search index and prepare query once per filter
Selectors (model, settings, file/tree, slash, OAuth) re-filter the same
stable candidate list on every keystroke. fuzzyRank was re-normalizing the
query once per candidate (~400x/keystroke) and rebuilding each candidate's
search index from scratch on every keystroke.

- prepareQuery/fuzzyMatchCore: normalize + split the query a single time in
  fuzzyRank instead of per candidate. Pure win on warm and cold paths.
- indexCache: memoize the per-text SearchIndex across keystrokes, with
  conservative admission -- texts >4 KiB bypass the Map entirely (no memory
  bloat from pasted prompts/transcripts searched via the message selector),
  and admission stops at the cap instead of evicting (a stream of unique
  one-off texts can't churn the map).

Incremental typing over a 400-item list drops ~58% (6.7ms -> 2.8ms for an
8-keystroke session); first-keystroke (cold) latency is unchanged (~0.5ms),
as the query-prep savings offset the cache overhead. Match ranking is
byte-identical, enforced by a golden-checksum guard in the new benchmark and
contract tests.

Adds packages/tui/bench/fuzzy.bench.ts (deterministic corpus, cold-start
session measurement, ranking-drift guard) and fuzzy contract tests for cache
transparency and the empty-normalized-query callback behavior.
2026-06-29 12:55:09 -07:00
can1357 9320f53664 test(tui): enabled slash command fallback and refined notification logic
- Allow mid-prompt slash tokens (e.g., `/tmp`) to fall back to file-path completion when no matching skill is found.
- Update notification eligibility logic to allow D-Bus delivery for in-band terminals while excluding Bell-only protocols.
- Add test case verifying slash-command fallback behavior for file paths.
2026-06-28 09:52:44 +02:00
can1357 ccf2b1adf6 feat(tui): implemented protocol-based detection for desktop notifications
- Removed the hardcoded terminal whitelist for native notifications in favor of protocol-based detection.
- Updated Warp terminal configuration to prefer `NotifyProtocol.Osc9` over `NotifyProtocol.Bell`.
- Simplified notification delivery logic by delegating D-Bus toast filtering to terminal protocol capabilities.
2026-06-28 09:52:44 +02:00
can1357 2bd840a20f Merge remote-tracking branch 'origin/farm/4678e70c/fix-iterm-shift-enter' 2026-06-28 08:41:17 +02:00
can1357 670d60fa60 feat(tui): added file-path completion support to autocomplete provider
- Added `getForceFileSuggestions` and `shouldTriggerFileCompletion` to `AutocompleteProvider` interface.
- Updated `Editor` to invoke file completion logic dynamically when providers support it.
- Corrected log viewer scroll offset calculation to account for viewport height.
- Added comprehensive unit test for log row selection and expansion.
2026-06-28 08:25:32 +02:00
roboomp f761171f68 refactor(tui): split keyboard enhancement into enter/exit pair
Renamed the buffer-switch helper to keyboardEnhancementEnterSequence and added a sibling keyboardEnhancementExitSequence so callers can balance push/pop generically instead of hard-coding the kitty pop.

ProcessTerminal returns the matching kitty pop on exit when kitty is active, and null when only the xterm modifyOtherKeys fallback is active: modifyOtherKeys is a global terminal flag with no per-screen stack, so emitting >4;0m on overlay exit would clear it on the normal screen and break composer typing between overlays. terminal.stop() and the emergency-restore path still disable it globally on graceful teardown.

TUI alt-screen entry/exit and resize alt-screen helpers now route through the new pair with fallbacks to kittyEnableSequence for custom Terminal implementations predating the new properties.

Fixes #3705
2026-06-28 06:25:26 +00:00