Op: correct
Restores: ref:44e5e0bb8 — queued /skill: chip lifecycle parity with plain-text steer
EventController.#handleMessageStart now mirrors the user-role refresh in
the custom branch, gated on readPendingDisplayTag(details). Without this,
AgentSession's tag-keyed dequeue mutated #steeringMessages /
#followUpMessages correctly but pendingMessagesContainer kept painting
the stale chip until an unrelated trigger (next user submit, dequeue key,
compaction flush) fired a refresh.
Non-queued custom variants (ttsr-injection, irc:*, async-result,
hookMessage) skip the refresh — they never registered a pending chip, so
rebuilding pendingMessagesContainer for them would be pure waste.
Pairs with the existing E4 (array splice) regression — the new E10 covers
the UI-refresh side of the same dequeue event with both positive and
negative gate assertions.
Co-Authored-By: chatgpt-codex-connector[bot] (P2 review on PR #1043)
- Updated event-controller read-tool streaming handling to wait for a parseable target before routing tool calls, avoiding early component binding for unresolved arguments.
- Allowed internal-URL read calls to bypass the regular read grouping path and fall through to direct tool execution.
- Adjusted read tool rendering to honor the computed `expanded` flag for completed output instead of forcing expanded output.
- Added readArgsTargetInternalUrl in the read tool group component to detect targets handled by InternalUrlRouter from path or file_path arguments.
- Updated event-controller and UI helper read rendering paths to skip grouping read tool calls when those arguments target internal URLs.
- Passed session cwd and settings into internal URL resolution in read.ts and added tests for internal versus non-internal target detection.
- Updated addMessageToChat in UI helpers and InteractiveModeContext to return rendered components instead of void.
- EventController now tracks IRC message components and removes them after a 10-second TTL, avoiding duplicate expiry scheduling per message signature.
- EventController dispose now clears all pending IRC expiry timers and tests were added for immediate render, TTL removal, duplicate suppression, and timer cleanup.
- Added asynchronous Kitty conversion for assistant tool images using `convertToPng`, keyed per tool-call entry with cached and in-flight tracking.
- Updated assistant image rendering to prefer converted PNGs for Kitty terminals while preserving existing behavior for other protocols.
- Added a unit test that verifies WebP tool images are converted and rendered as Kitty image output instead of the raw image/webp fallback.
- Added a new `edit.hashlineAutoDropPureInsertDuplicates` boolean setting with default `false` for hashline edits.
- Threaded the setting through tool execution contexts so hashline previews and execution honor the configured option.
- Changed pure-insert duplicate boundary absorption to run only when enabled and added tests for default-disabled and enabled behavior.
- Added per-session retain queues with size/time auto-flush, recursive drain, and lifecycle flushes on end/clear/enqueue.
- Changed `hindsight-retain` to validate session state, enqueue writes, and return `Memory queued.` immediately.
- Added `notice` event support and handlers that route error/warning/status messages with source-aware formatting.
- Updated client and tests with shared request mapping, `RequestOptions`, `buildMemoryItem`, and expanded batch/list/doc APIs.
Streamed tool-call JSON can deliver `_i` as an object, number, or boolean
before schema validation lands. The optional-chain in
#updateWorkingMessageFromIntent only guarded null/undefined, so any
non-string value crashed the UI with 'intent?.trim is not a function'.
Accept `unknown` and bail unless typeof intent === 'string', mirroring
the typed guard in agent-loop's extractIntent. Drop the misleading
`as string | undefined` cast at the streaming call site.
Fixes#900
- Removed title-source aware branching from session terminal-title and accent helpers, and updated callers to use session name plus cwd only.
- Dropped UUID-based recent-session naming by preferring explicit header titles or first user prompts and generating an "Untitled · <time>" fallback.
- Adjusted welcome session-row rendering for width-aware name truncation and disabled reasoning in title generation requests to keep terminal titles concise.
- Tracked locally submitted user signatures for both optimistic and streamed-queue submissions in interactive-mode context state.
- Updated user message_start handling to avoid re-clearing the editor and re-adding chat for locally originated messages.
- Cleared consumed local signatures on queued-message restore and added tests for queued, external, and optimistic message_start editor behavior.
- Added an `irc_message` session event carrying custom IRC messages and emitted it when IRC records are created.
- Registered an IRC message handler in EventController that skips duplicate messages by role, custom type, and timestamp.
- The handler now appends IRC messages to chat, resets read grouping, and triggers a UI render.
- Replaced `AgentTool` `nointent` and `deriveIntent` with a unified `intent` option that supports `omit`, `optional`, `require`, or a callback function.
- Updated agent tool schema injection and execution paths to inject `_i` as required/optional/omitted and to derive intent through the new `intent` callback.
- Aligned atom-edit tests with the updated default sed behavior (`g` now off by default and explicit `g: true` for global replacement).
- Added `nointent` and `deriveIntent` to `AgentTool`, and made intent-schema injection honor `PI_NO_INTENT` plus per-tool opt-outs.
- Updated tool execution and streaming UI handling to derive a fallback intent when `_i` is absent, without aborting on derivation failures.
- Marked several coding tools as `nointent` and added `deriveIntent` callbacks where needed, then relaxed prompt language to indicate intent is present on most tools.
- Canonicalized file and CLI defaults from `read` to `open` across tool registration and prompts.
- Added `resolveToolAlias()` and applied alias-normalized tool selection so legacy `read` maps to `open`.
- Updated runtime, UI, and export layers to treat `open` as first-class while preserving `read` compatibility.
- Renamed read prompt docs to `open.md`/`open-chunk.md` and refreshed system guidance to recommend `open`.
- Updated tool-related tests and expectations from `read` to `open` (including test fixtures and aliases).
- Added a new read.toolResultPreview boolean setting defaulting to false to control inline read result rendering.
- Updated read tool group rendering to show inline previews only when enabled and to hide duplicate summary rows for previewed entries.
- Passed the setting through event and UI helper constructors and added tests for default-off behavior and the duplicate-preview summary case.
- Added vim tool-call IDs across EventController, UiHelpers, and ToolExecution for per-call preview mapping.
- Extended Vim type and command parsing with update/write, edit, global, yank, and put handling.
- Added Vim engine support for new commands and motions, including gJ, g*, g#, g_, |, and gu/gU/g~.
- Reworked Vim tool flow to cache per-file engine clones, reuse tool details, and stream inserts in chunks.
- Updated vim.md and changelog to document new vim keys, ex aliases, and fixed :global preview behavior.
- Added parser and renderer tests plus a tmp/vim_test.txt fixture for chunked, cursor, and partial-insert cases.
- Added multi-file edit payload support by requiring per-entry `edits` arrays across patch, hashline, replace, and chunk modes.
- Changed edit schemas and validators to move `path` (and `sel`->`path`) and op data into each edit entry.
- Changed edit execution flow to parse `file:selector` paths, run single-entry executors per file, and return grouped per-file results.
- Updated chunk diff rendering and test expectations to emit consistent anchor gutters with spaced pipes and `^` head-line markers.
- Propagated session title source through terminal-title update calls so auto and user names are handled consistently across controllers.
- Suppressed auto-generated names in status-line segments and completion messages by falling back to cwd-based titles.
- Updated title formatter tests to verify auto-generated and user-specified session titles produce different terminal labels.
- Extracted large switch statement into 16 dedicated event handler methods for improved maintainability and type safety.
- Introduced AgentSessionEventHandlers type and handler dispatch map to enable compile-time verification of event coverage.
- Fixed memory leak by cancelling idle compaction timer on event controller disposal.
- Fixed session resumption to preserve last non-empty session when starting fresh.
- Fixed stash detection to use git ref resolution instead of output parsing for reliability.
- Fixed secret obfuscation to deobfuscate restored session messages locally while keeping LLM messages obfuscated.
- Fixed stash pop operation to preserve staged changes with --index flag after task branch merges.
- Changed idle compaction settings from enum to numeric type for flexible configuration.
* feat(rules): implemented alwaysApply auto-injection into system prompt
rules with alwaysApply: true were parsed by all providers and used to
exclude the rule from rulebookRules, but the inclusion half was never
built — rule content was silently dropped. now:
- full content is injected directly into the system prompt (before the
rulebook rules section) in both default and custom prompt templates
- rules remain addressable via rule:// for re-reading
- ttsr rules still take priority (condition + alwaysApply goes to ttsr only)
updated rulebook-matching-pipeline.md to reflect the three-bucket split
(ttsr > always-apply > rulebook) and corrected the rule:// resolution
docs.
* feat(browser): implement screenshot path saving
- Add `browser.screenshotDir` setting (tools tab) for a persistent
default screenshot directory, configurable via /settings
- Honour the existing `path` parameter in the screenshot action,
which was declared in the schema but never consumed by the implementation
- Resolution order: params.path (abs) > join(screenshotDir, params.path)
> join(screenshotDir, screenshot-<timestamp>.png) > /tmp only
- Writes full-resolution buffer to disk (not the API-compressed copy)
- Creates destination directory recursively if it doesn't exist
- details.screenshotPath reflects the actual saved location
Fixes: path param silently ignored since removal in v11.5.0
* feat(browser): expand ~ in screenshotDir and path params
Users can now configure browser.screenshotDir as ~/Downloads or
~/Pictures and use params.path as ~/screenshots/foo.png without
needing to supply fully-qualified paths.
* fix(browser): write screenshot to exactly one location
Previously wrote to /tmp unconditionally then copied to user path,
resulting in two files. Now resolves a single destination upfront:
1. params.path (absolute, or relative to screenshotDir/cwd)
2. screenshotDir + auto-timestamp filename
3. /tmp fallback (original behaviour, unchanged)
Also: user-defined destinations receive the full-res buffer;
/tmp fallback retains the API-compressed copy as before.
* feat(settings): add text input support for plain string settings
Settings with type: "string" and no submenu now render as an editable
text field in the /settings TUI panel instead of being silently skipped.
- settings-defs.ts: add TextInputSettingDef interface; pathToSettingDef
falls through to { type: "text" } for any plain string schema entry
- settings-selector.ts: add TextInputSubmenu class (mirrors
ConfigInputSubmenu from plugin-settings.ts); add "text" case to
#defToItem; add #createTextInput method
This makes browser.screenshotDir visible and editable in the Tools tab.
Empty field on submit clears the setting (falls back to /tmp behavior).
* fix(settings): text input — cursor at end, block tab navigation
- Cursor: call handleInput(ctrl+e) after setValue to jump to end of
pre-filled string instead of leaving it at position 0
- Tab/arrow guard: add #textInputActive flag; suppress tab-switch and
left/right routing to tab bar while a TextInputSubmenu is open, so
arrow keys reach the Input component's cursor movement handlers
instead of switching settings tabs
* fix(browser): expand ~\ (Windows backslash) in screenshot paths
expandHome now handles both Unix ~/... and Windows ~\... separators,
matching user expectation on all platforms. Addresses Codex review.
* fix(coding-agent): use expandPath for screenshots
* docs: add changelog for screenshot path option
Bug fixes:
- Add browser.screenshotDir to settings-schema.ts (lost during rebase conflict)
- Fix stale expandHome comment to expandPath in settings-selector.ts
- Final screenshotDir description: Directory to save screenshots with ~ support
* fix: biome format corrections for screenshot-path-option branch
* fix: add missing #textInputActive field and screenshotDir default
* fix(browser): align screenshot metadata with saved file contents
When screenshotDir or params.path is set, the full-resolution PNG buffer
is written to disk. Previously mimeType/bytes in details still reflected
the resized payload sent to the model, making metadata inconsistent with
the actual saved file.
Now savedBuffer/savedMimeType track what is written, and details reflects
that. Display output distinguishes 'Saved' vs 'Model' when full-res is
used, and collapses to a single Format/Dimensions line for temp-only.
* fix(browser): resolve params.path relative to cwd regardless of screenshotDir
screenshotDir is a default save location, not an anchor for explicit
paths. A relative params.path should always resolve against cwd so its
semantics are stable and predictable regardless of user settings.
* fix(tui): enforce strict line budget for collapsed tool output
The grep, ast_grep, and ast_edit renderers used group-count-based
collapse that always included the first group unconditionally,
allowing collapsed output to remain visually large when a single
group contained many lines.
Add maxCollapsedLines to renderTreeList that enforces a strict
total-line cap in collapsed mode. Items that exceed the remaining
budget are skipped entirely (no broken fragments). The isLast tree
branch is computed after the budget check to avoid double-last
branches when a summary line follows.
Remove the per-tool getCollapsedMatchLimit / getCollapsedChangeLimit
helpers that are now redundant.
Fixes#455
Made-with: Cursor
* WIP
* WIP
* cleanup
* docs(coding-agent): update changelog for custom model tags and cycle order
* Fix custom model precedence across load and refresh
* feat(ask): add multiline editor support for custom input
* feat(extension-ui): add dialog options and abort signal support to editor
* docs(ask): add multiline editor and timeout behavior guidance
* docs(ask): simplify multiline input documentation
* fix(tui): preserve terminal scrollback during full redraws
Replace destructive \x1b[3J\x1b[2J\x1b[H full-redraw sequence with
scrollback-preserving repaint helpers:
- seedTranscript: first paint with no prior frame, writes full transcript
without clearing scrollback
- repaintViewport: trusted-frame repaints that scroll viewport-shift
delta into scrollback before overwriting visible rows in-place
- Height-increase handler that pushes revealed scrollback back before
reclaiming the display
Replace requestRender(true) state destruction with a one-shot
without resetting #previousLines or cursor bookkeeping.
Track #previousHeight to detect terminal height increases that pull
scrollback lines into the visible area.
fixes#507
* fix(tui): fix exit gaps, content shrink drift, and overlay cursor recovery
- Rewrite stop() to use viewport-relative cursor positioning instead of
content-length, preventing blank gaps when content is shorter than viewport
- Replace trailing \r\n\x1b[2K clear loops in repaintViewport() and
height-increase path with \r\n\x1b[J to avoid cursor drift past content
- Add 12 TUI regression tests for exit gaps, content shrink, and overlay
dismiss cursor recovery
- Add 6 coding-agent controller tests for /new and /tree commands
* fix(tui): redraw sparse height increases atomically
* fix(coding-agent,tui): address review regressions
* fix(tui): reseed after terminal resume
* test(ai): avoid leaking kagi module mocks
* fix(ask): keep multiline custom input in prompt gutter
* fix(ask): preserve multiselect choices on editor dismiss
* fix(ask): honor app interrupt in prompt editor
* fix(coding-agent): preserve new-session approval state
* feat(core): add session-scoped model/provider retry fallback policy
* feat(core): validate retry fallback chains on session startup
* fix(ask): preserve prior answer when custom editor dismissed in single-select
* fix(core): harden retry fallback policy semantics
* fix(core): correct retry fallback edge cases
* test(coding-agent): removed macOS fallback test case from theme detection
- Removed test case for macOS fallback behavior inside Zellij.
* refactor: simplified null checks using optional chaining across TypeScript and Rust modules
- Simplified null/empty checks across TypeScript codebase using optional chaining operator (?.) for improved readability.
- Replaced explicit null checks in validation logic with optional chaining in oauth-discovery, gemini-cli, claude, zai, and lsp modules.
- Updated error handling in Rust command invocation to use double question mark operator (??) for cmd_result.
- Consolidated null validation patterns across tools (bash-skill-urls, browser, gemini-image, resolve) and keybindings using optional chaining.
* chore: bump version to 13.15.1
* fix(core): address PR review on fallback retry behavior
* test(ai): refactored auth storage test to use spyOn for cleaner mocks
- Refactored auth storage test to use vi.spyOn() instead of vi.mock() for cleaner mock management.
- Simplified mock type definitions by leveraging bun:test's Mock type import.
* chore: bump version to 13.15.2
* Fix stale OpenAI Responses replay across session boundaries (#534)
* Fix stale OpenAI Responses replay across session boundaries
Fixes#505
* Fix CI tests for session replay change
* Harden session reload and switch rollback
* Guard session switch snapshots
* fix(coding-agent): preserve responses replay snapshots
* Normalize pasted image formats before attach (#543)
Co-authored-by: iter <itertoolz@gmail.com>
* Allow overriding the Codex web search model (#516)
* Allow codex web search model override
* Handle blank codex web search model
* feat(ai): add gemini-3.1-pro-preview models to google-vertex provider (#521)
Add gemini-3.1-pro-preview and gemini-3.1-pro-preview-customtools to
the google-vertex provider in models.json, matching the existing
google-generative-ai entries.
Fixes#520
Co-authored-by: Muness Castle <munesscastle@artium.ai>
* Make temporary model selector keybinding configurable (#539)
Fixes#533
* chore: bump models.json
* refactor(coding-agent): migrated test mocks to vitest spyOn with Symbol.dispose cleanup
- Migrated test mocking from bun:test mock API to vitest spyOn pattern across 9 test files.
- Extracted mock setup logic into reusable helper functions with Symbol.dispose cleanup pattern.
- Replaced manual beforeEach/afterEach and try-finally blocks with TypeScript 5.2 using declarations.
- Removed 178 lines of boilerplate mock initialization and restoration code from test suite.
* chore: bump version to 13.15.3
* fix(ask): restore prompt-style enter handling
* fix(tui): avoid blank scrollback regressions
* fix(models): keep same-id replacements authoritative
* fix(tui): enforce collapsed line budgets
* fix(models): unify selector role sources
* fix(rules): dedupe always-apply prompt injection
* fix(browser): show saved screenshot path
* style: format merged PR fixes
* refactor(coding-agent): restructured screenshot and prompt utilities into focused helpers
- Extracted screenshot formatting logic into dedicated `formatScreenshot()` function with options support.
- Consolidated prompt source deduplication into `dedupePromptSource()` helper to prevent rule duplication.
- Refactored editor text sanitization to use `replaceTabs()` utility for consistent tab width handling.
- Added test coverage verifying editor respects configured tab width when loading text programmatically.
* refactor(coding-agent): restructured validation and rendering for consistency
- Refactored theme color validation to use single source of truth with THEME_COLOR_RECORD object.
- Simplified model registry to defer per-model overrides to dedicated method and use constant for role IDs.
- Refactored tree list rendering to pre-render items once for consistent line counts across phases.
- Refactored question result formatting to use early returns and consistently include question ID in output.
- Updated hook editor hint text to include ctrl+g external editor option when prompt style is enabled.
- Removed unused isLogicalLineStart property from LayoutLine interface in editor component.
* revert: 535 due to TUI regressions
* test(coding-agent): corrected hook-editor assertion for keybinding render
- Corrected assertion in hook-editor test to verify external editor keybinding is rendered.
* feat(tools): added root path alias to resolve bare / to working directory
- Added root path alias feature to resolve bare `/` to session working directory in path resolution.
- Updated browser tool to use `resolveToCwd()` for consistent workspace-relative path handling.
- Added comprehensive test suite validating root path alias resolution across grep, read, find, ast_grep, and ast_edit tools.
* feat(prompts/tools): clarified hashline block boundary handling with examples
- Improved hashline tool documentation with clearer guidance on block boundary handling and closing delimiter duplication prevention.
- Added concrete example demonstrating correct anchor placement when replacing entire blocks including closing braces.
- Reorganized boundary duplication warnings into actionable self-check guidance with visual comparison steps.
* chore: bump version to 13.16.0
* fix(coding-agent): fixed python kernel startup hangs (#548)
* fix(coding-agent): fixed python kernel startup hangs
* fix(coding-agent): fixed startup timeout regressions
* fix(coding-agent): preserved startup cancellation typing
* perf(pi-natives): optimized memory allocation with MiMalloc integration
- Integrated MiMalloc as global allocator to improve memory allocation performance.
* feat: fff
- Added SearchDb class for stateful shared search database instances enabling persistent file indexing and frecency tracking across grep, glob, and fuzzyFind operations.
- Added optional db parameter to grep(), glob(), and fuzzyFind() functions for database-backed searching with improved performance via cached file indices.
- Replaced grep-searcher with fff-grep and added fff-search dependency for enhanced file discovery and search capabilities with memory-mapped file support.
- Migrated fuzzy file discovery from fd module to fff module with SearchDb integration for stateful caching and improved search performance.
- Exported SearchDb type from @oh-my-pi/pi-natives public API for type-safe usage in grep, glob, and fuzzyFind workflows.
* feat(pi-natives): added unified picker coordination for file search operations
- Added `wait_for_picker_scan()` function to search_db module with cancellation token support for polling picker scan completion.
- Integrated picker-based file search into glob matching logic with `collect_files_from_picker()` helper to reuse shared SearchDb picker results.
- Refactored fff and grep modules to use centralized `wait_for_picker_scan()` wrapper instead of direct FilePicker calls, improving cancellation handling.
- Propagated SearchDb instance through agent session initialization and input controller to enable unified file picker coordination across search operations.
* chore: bump version to 13.16.1
* fix: install zig in CI
* feat(tui): make inline image max-width configurable via tui.maxInlineImageColumns (#551)
* feat(tui): make inline image max-width configurable via tui.maxInlineImageColumns
* fix(tui): handle 0 as unlimited in maxInlineImageColumns; drop || undefined coercion
* feat(browser): auto-detect NixOS and use system Chromium (#550)
Puppeteer's bundled Chromium is a dynamically-linked FHS binary that
cannot run on NixOS. On startup, resolveSystemChromium() checks for
/etc/NIXOS and searches for a usable binary in order:
1. chromium on PATH
2. chromium-browser on PATH
3. ~/.nix-profile/bin/chromium
4. /run/current-system/sw/bin/chromium
The resolved path is passed as executablePath to puppeteer.launch().
Result is cached per process. On non-NixOS systems the function returns
undefined immediately, leaving Puppeteer's default resolution intact.
* feat(pi-natives): added automatic parenthesis escaping in regex patterns
- Added automatic escaping of unescaped parentheses in regex patterns when group syntax errors occur, enabling literal function call patterns like `fetchAnthropicProvider(` to work as search queries.
- Extracted regex matcher builder into separate function for reusability and error recovery logic.
- Added 2 test cases validating parenthesis escaping behavior for both escaped and literal parentheses.
- Fixed documentation formatting in sanitize_braces comment.
* style: reformat
* chore: bump version to 13.16.2
* fix: only show update banner when npm version is strictly newer (#552)
* fix(ai): corrected OAuth credential updates to replace in-place instead of accumulating soft-deleted rows
- Fixed OAuth credential updates to replace matching credentials in-place rather than creating disabled rows, preventing unbounded accumulation of soft-deleted credentials.
- Modified OAuth credential saving to preserve unrelated identities instead of replacing all credentials for a provider.
- Updated credential identity resolution to use provider context for more accurate email deduplication.
- Implemented upsertAuthCredentialForProvider method to handle credential matching and in-place updates.
- Added 5 test cases covering credential preservation across reauth, multi-account scenarios, and stale cache handling.
* chore: bump version to 13.16.3
* feat: introduced unified range API for hashline edits and model catalog updates
- Simplified hashline edit location API by replacing separate `line` and `block` properties with unified `range` property accepting `{ pos, end }` anchors.
- Renamed hashline helper functions from `hlineref`/`hlinefull` to `href`/`hline` for improved brevity and consistency.
- Added detection for `kysely-codegen` generated files in auto-generated file guard with corresponding test coverage.
- Added 13 new AI model configurations and updated token limits and pricing for existing models across multiple providers.
- Enhanced file type validation in grep native to reject symlinks, FIFOs, sockets, and non-regular files with improved error handling.
* chore: bump version to 13.16.4
* fix: pin rustc-hash to 2.1.1 to avoid SIGILL on CI
rustc-hash 2.1.2 (released today) refactored hash_bytes to use
split_first_chunk, which produces illegal instructions when compiled
with nightly + -C target-cpu=x86-64-v3 on CI runners.
* fix(ci): pin nightly to 2026-03-27 to avoid codegen SIGILL regression
Today's nightly produces illegal instructions when compiled with
-C target-cpu=x86-64-v3. Reverts the unnecessary rustc-hash pin from
the previous commit since the real cause is the nightly compiler.
Also lets Cargo.lock return to rustc-hash 2.1.2 (not the culprit).
* fix(ci): add rustup target fallback for pinned nightly cross-compile
* fix(coding-agent): do not prompt to use grep and find tools if they are disabled (#566)
Co-authored-by: le-cameleon <200889489+le-cameleon@users.noreply.github.com>
* fix(natives): skipped grep special files (#565)
avoided opening fifos and other special filesystem nodes during grep and added fifo regressions in native and coding-agent tests.
* fix: skill baseDir regex fails on Windows backslash paths (#554)
The regex that strips SKILL.md from the path to compute baseDir only
matches forward slashes. On Windows where paths use backslashes, the
replace is a no-op and baseDir equals the full SKILL.md file path.
This breaks sub-path resolution for skills: the subpath gets appended
to the SKILL.md file path instead of the skill directory.
Fix: use character class matching both path separators.
---------
Co-authored-by: deadcode-walker <268043493+deadcode-walker@users.noreply.github.com>
Co-authored-by: Rens Tillmann <rens@super-forms.com>
Co-authored-by: haiyang.zhou <haiyang.zhou@seamoney.com>
Co-authored-by: Leo P <junk@slact.net>
Co-authored-by: Zakhar Kogan <36503576+zaharkogan@users.noreply.github.com>
Co-authored-by: Vu Anh Nguyen <vuanhng00@gmail.com>
Co-authored-by: can1357 <me@can.ac>
Co-authored-by: daandden <64765666+daandden@users.noreply.github.com>
Co-authored-by: iter <72358817+itertea@users.noreply.github.com>
Co-authored-by: iter <itertoolz@gmail.com>
Co-authored-by: Cheol Kang <dev@cheol.me>
Co-authored-by: Muness Castle <931+muness@users.noreply.github.com>
Co-authored-by: Muness Castle <munesscastle@artium.ai>
Co-authored-by: zamo <falby97@proton.me>
Co-authored-by: elikoga <elikowa@gmail.com>
Co-authored-by: BayLee4 <63376748+BayLee4@users.noreply.github.com>
Co-authored-by: le-cameleon <200889489+le-cameleon@users.noreply.github.com>
Co-authored-by: Wiedzmin <56316383+art-wiedzmin@users.noreply.github.com>
- Schedule auto-removal of completed/abandoned tasks after ~1 minute delay
- Strip already-done tasks when restoring session from branch history
- Add todo_auto_clear event to trigger UI refresh on removal
- Add blank line before Todos header for visual spacing
* feat: spill large tool results to artifacts, show tail
- Add centralized spillLargeResultToArtifact() in wrappedExecute pipeline
- Tool results exceeding 50KB saved as session artifacts via saveArtifact()
- Content truncated to tail (20KB / 500 lines) instead of head
- Truncation notice includes artifact:// reference for full output retrieval
- Skip spill when tool already saved its own artifact (bash/python/ssh)
- Update formatFullOutputReference to use action-oriented wording
* feat: per-turn token usage display on assistant messages
* fix: TS errors in output-meta truncation fields
Three early-return paths in #runAutoCompaction emitted auto_compaction_end
with result=undefined, aborted=false, and no errorMessage when compaction
was legitimately not needed (no model selected, no candidate models
available, or nothing to compact yet). The event-controller had no way to
distinguish these benign skips from a genuine failure, and fell through to
show the warning:
'Auto context-full maintenance failed; continuing without maintenance'
This was visible after a successful compaction: the next threshold check
would find nothing new to compact (prepareCompaction returns null), emit a
soft-skip event, and trigger the false warning.
Add skipped?: boolean to the auto_compaction_end event type and set it on
the three soft-skip paths. Update the event-controller to treat skipped
events as silent no-ops. Propagate the field through the extension and
hook AutoCompactionEndEvent interfaces so extensions can observe the
distinction.
- Extracted loading animation lifecycle management into centralized ensureLoadingAnimation() method.
- Consolidated duplicate loading animation setup across event-controller and interactive-mode into single reusable method.
- Updated showError() to properly clean up loading animation state when errors occur.
- Added comprehensive test coverage for InputController escape key behavior with optimistic submission.
The manual /compact command path in executeCompaction() called
rebuildChatFromMessages() but never added the compactionSummary
message to the chat. The auto-compaction path in event-controller
explicitly adds it, but the manual path was missing this step.
Capture the CompactionResult returned by session.compact() and
render the summary via addMessageToChat(), matching the behavior
of the auto-compaction flow.
Co-authored-by: Miroslav Drbal <miroslav.drbal@gendigital.com>
- Extracted OAuth identifier logic into public functions extractOAuthCredentialIdentifiers and extractOAuthTokenIdentifiers.
- Replaced single credentialIdentity string with multi-identifier resolveCredentialIdentifiers returning string[] for flexible matching.
- Changed credential deduplication from email-based to accountId-based matching in replaceAuthCredentialsForProvider.
- Updated auth-storage tests to verify accountId-prioritized deduplication behavior across soft-disable and hard-delete scenarios.
- Added documentation comments in coding-agent modules explaining partial JSON preservation for streaming tool previews.
- Documented streaming tool preview requirements and render paths in AGENTS.md.
- Added `env` parameter to bash tool for safe environment variable passing without shell re-parsing.
- Added support for rendering partial environment variable assignments in command preview during streaming.
- Updated bash tool prompt to recommend `env` parameter for multiline, quote-heavy, and untrusted values.
- Refactored tool execution component to conditionally merge partial JSON arguments during streaming.
- Added helper functions for environment variable normalization, escaping, and formatting.
* idiomatic rust fixes
* idiomatic rust fixes
* display an image if we are fetching an image
* MIME type strictness
* codex nagging me
* codex nagging
* handoff instead of compaction as context filled strategy and surfacing
* handoff instead of compaction as context filled strategy and surfacing p2
* handoff instead of compaction as context filled strategy and surfacing p3
* handoff instead of compaction as context filled strategy and surfacing p4
* handoff instead of compaction as context filled strategy and surfacing p5
* handoff instead of compaction as context filled strategy and surfacing, fixes
* failing fetch test from the fetch tool updates
* handoff focus prompt skeleton
* handoff focus prompt skeleton p2
* fetch bugs
* further codex improvements
* further codex improvements
---------
Co-authored-by: Brit <lol@no.com>
- event-controller: check async state for inlined image read results
instead of hardcoding isBackgroundRunning=false
- ui-helpers: fall through to render text blocks when read results
contain both images and text
- terminal-capabilities: return null for unknown PI_FORCE_IMAGE_PROTOCOL
values instead of silently falling through to fallback detection
- Added async background job execution for bash and task tools with configurable concurrency limits and automatic result delivery.
- Added cancel_job tool and /jobs slash command to manage and inspect running background jobs with status display.
- Added jobs:// internal protocol handler for querying job status and retrieving job execution details.
- Added async.enabled and async.maxJobs settings to control background job execution behavior.
- Enhanced status line to display count of running background jobs with visual indicator.
- Implemented AsyncJobManager with exponential backoff retry delivery, job lifecycle tracking, and automatic eviction.
Fixes#56.
- Added streamed tool intent display in working message to show real-time intent tracking during agent execution.
- Changed intent tracing field name from `$intent` to `_intent` across tool schemas and agent core for consistency.
- Added support for file deletion and renaming operations in hashline edit mode.
- Renamed hashline edit operation fields: `set` to `target`/`new_content`, `set_range` to `first`/`last`/`new_content`, `insert` to `inserted_lines`.
- Implemented caching for tool output block rendering to avoid redundant computations on re-renders.
- Enhanced read tool grouping to prevent coalescing across narrative boundaries (text/thinking blocks between tool calls).
- Improved string preview formatting to detect multi-line strings and display line counts with ellipsis indicators.
- Refactored tool execution component to use reactive render state tracking for better state management.
- Enhanced error handling in tool renderers with logging for failures.
- Fixed truncation indicator to use ellipsis character instead of verbose suffix.
- Fixed model switches deferred during streaming to apply correctly when the stream completes, preventing model changes from being lost.
- Added pendingModelSwitch field to track deferred model changes during active streams.
- Added flushPendingModelSwitch() method to apply deferred model switches after streaming completes.
- Modified switchToPlanModel() to defer model changes when a stream is active instead of applying immediately.
- Modified exitPlanMode() to defer model restoration when a stream is active instead of applying immediately.
- Modified EventController to call flushPendingModelSwitch() when stream completion is detected.
- Added terminal-capabilities module with NotifyProtocol enum and notification formatting/sending methods to TerminalInfo class.
- Renamed TERMINAL_INFO export to TERMINAL and consolidated terminal image/capability exports from terminal-image to terminal-capabilities module.
- Removed terminal-image module exports from public API with functionality migrated to terminal-capabilities.
- Simplified notification settings in coding-agent by removing protocol detection logic and delegating to TERMINAL.sendNotification().
- Removed terminal-notify.ts utility module from coding-agent, consolidating notification handling into pi-tui package.
- Changed TextInput type parameter to string in truncateToWidth(), visibleWidth(), sliceWithWidth(), and extractSegments() functions in native bindings.
- Removed TextInput type export from public API of pi-natives package.
- Removed format.ellipsis symbol from theme configuration, replacing all theme-based ellipsis references with hardcoded Unicode ellipsis character (...).
- Removed ellipsis property from SymbolTheme interface in pi-tui package.
- Removed truncateToWidth, sliceWithWidth, and extractSegments wrapper functions from pi-tui public API, now re-exporting directly from pi-natives.
- Added early return optimizations in truncateToWidth() and sliceWithWidth() native functions to skip native calls when possible.
- Replaced SettingsManager class with new Settings singleton providing synchronous get/set API and background persistence.
- Introduced settings-schema.ts as single source of truth for all configuration definitions with 100+ settings organized into logical groups.
- Migrated from method-based settings access (getTheme(), setTheme()) to path-based access using dot notation (settings.get('theme'), settings.set('theme', value)).
- Removed 2035-line settings-manager.ts file and replaced with modular settings.ts (693 lines) and settings-schema.ts (836 lines) for improved maintainability.
- Unified settings schema into single source of truth eliminating duplicate definitions across settings-defs.ts and settings-manager.ts.