- Added edit streaming fallback data to the edit render context and used it when no finalized patch text was available.
- Implemented hashline fallback rendering that strips envelope syntax, sanitizes text, and truncates output to a fixed number of lines with a streaming indicator.
- Updated tool execution to populate the fallback preview from the active edit strategy and added a renderer test for hashline envelope input while the diff is not yet computable.
- Trim logo from 14w to 12w (2-wide legs).
- Diagonal BL→TR gradient instead of per-line LTR.
- Truecolor: 3-stop magenta→violet→cyan path that skips the deep-blue valley.
- 256-color: same 6-stop ramp as fallback.
- Compute the colored logo once at module load instead of per render.
- 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.
Add an explicit openai-models-list discovery type for custom providers while keeping lm-studio as a compatible alias. Custom providers can now point baseUrl at an OpenAI-compatible /v1 endpoint, provide an api key, and auto-populate models via GET {baseUrl}/models.
Discovered models merge cleanly with user-defined models from models.yml/models.json, so YAML entries still win for display name and token limits. The provider picker now explains when discovery succeeds but returns zero models, and when the configured /models endpoint responds with 404.
Fixes#970
The custom status line rendered cache_read with the input icon and
cache_write with the output icon — backwards relative to Anthropic's
cache_creation_input_tokens (write) / cache_read_input_tokens (read)
semantics. Swap the icon pairings in status-line/segments.ts and the
labels in status-line-segment-editor.ts to match.
Fixes#953
- Exported hashline section interfaces and helpers, including a new section-diff API for external callers.
- Refactored `computeHashlineDiff` to split input sections, propagate split errors, and delegate each section via helper.
- Added context-highlight caching and batched highlighting for unchanged lines, with `replaceTabs` fallback on unknown files.
- Fixed hashline streaming preview so completed sections stay visible when a new `@PATH` header appears mid-stream.
- Added hashline streaming tests for section persistence, malformed trailing `+ 7`, and dual sections.
- Converted systemPrompt APIs and state types to ordered `string[]` across agent, AI, and coding-agent surfaces.
- Added `normalizeSystemPrompts` and applied it to context normalization before building provider request payloads.
- Updated AI providers to emit separate normalized prompt blocks/messages instead of a single merged system prompt.
- Removed dedicated `projectPrompt` state and remapped that context into system-context buckets in session, dump, and token accounting.
- Aligned tests and changelogs to pass and assert `systemPrompt` as arrays with ordered prompt semantics.
- 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.
- Updated read schema, path utilities, and dispatch to parse selectors from :raw/:L suffixes on path, removing standalone sel usage.
- Changed truncation/error notices to continue with :<nextOffset> and :1 guidance for read and sqlite pagination.
- Added summarizeCode support with tree-sitter summaries, read.summarize settings, and N-API Summary types/exports.
- Added tests and docs updates for path-embedded selectors, summary behavior, and explicit raw/offset SQL/read cases.
- Added session-draft persistence methods in SessionManager to write unsent editor text to an artifacts-sidecar draft file and delete it after single-shot consumption.
- Persisted editor text during interactive shutdown and restored that draft on resume when the editor was empty, enabling Ctrl+D draft recovery.
- Updated Ctrl+D handling in the editor/controller path and added tests covering draft round-trip, artifact cleanup, stale-draft eviction, and in-memory no-op behavior.
- Removed settings UI entries for `display.tabWidth`, `stt.language`, and similar values lacking valid `ui.options`.
- Refactored `pathToSettingDef()` in `settings-defs.ts` to derive submenu options directly from schema metadata.
- Introduced `SubmenuOption`/`AnyUiMetadata` in `settings-schema.ts` and added `options: "runtime"` support for dynamic lists.
- Removed the token_total segment from the default status-line preset.
- Kept the remaining left-side segment order unchanged, including cost at the end.
- Added `hindsight.scoping` and `HINDSIGHT_SCOPING` with global, per-project, and per-project-tagged modes.
- Migrated legacy `raw.hindsight` handling to scoping-based behavior and removed deprecated `dynamicBankId`/`agentName` keys.
- Replaced `deriveBankId` with `computeBankScope`, returning `bankId` plus optional retain/recall tags by mode.
- Forwarded scoped tags through memory ops so recall and retain/reflect calls use `tags`, `tagsMatch`, and `recallTags`.
- Validated `scoping` values from env/settings, warning and defaulting to `per-project-tagged` when invalid.
- Refactored setting definitions so the optional visibility predicate now lives on the shared base interface.
- Updated path-to-def mapping to pass the shared condition through every setting variant.
- Adjusted SettingsSelectorComponent to evaluate condition for all setting types before rendering items.
- Added `memory.backend` and `hindsight.*` settings schema with migration from `memories.enabled` legacy mode.
- Added Hindsight memory backend runtime modules for resolved config, client creation, bank ID derivation, and state lifecycle.
- Added off/local/hindsight backends and resolver wiring across SDK, commands, and compaction context.
- Added `hindsight_recall`, `hindsight_reflect`, and `hindsight_retain` tools with schema validation and backend gating.
- Added Memory tab metadata and symbols to expose backend selection in the settings UI.
- Added package export barrels and tests for bank ID, content formatting, and hindsight config env precedence.
- Added a new boolean statusLine.sessionAccent setting to settings schema and propagated it through status-line preview, controller, and component setting updates.
- Updated status line rendering and interactive border coloring to disable session-based accent colors when the setting is false.
- Added a regression test verifying the status-line gap uses theme border color instead of session accent when session accents are disabled.
Fixes#918
- Switched search/ast_grep/ast_edit/find inputs from scalar path fields to required `paths` arrays.
- Reworked path resolution to normalize and expand each `paths` entry via explicit helpers in `src/tools/path-utils.ts`.
- Updated search and find tool-call rendering to display explicit `paths` values in mode overlays and export views.
- Updated tool prompt docs and examples to document `paths` array inputs for search, grep, find, and AST tools.
- Raised the default search match limit from 20 to 500 and updated limit-reached messaging.
- 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.
- Added a unified eval framework with parser grammar, backend interfaces, and JS/Python execution result types.
- Added eval tool docs and updated prompts for fenced cells, `eval.py`/`eval.js`, and fallback behavior.
- Replaced the built-in `python` tool with `eval` across registry, rendering, interactive modes, and tool settings.
- Migrated Python execution runtime from `src/ipy` to `src/eval/py`, renamed state fields, and removed legacy introspection.
- Refactored browser tooling from in-process VM helpers to worker-managed tab supervisors and protocol transport.
- Added eval parser fallback and JS tool-bridge tests, updated imports, and removed obsolete python-mode suites.
- Documented and removed `utils/oauth` from the `ai` package entrypoint, noting it as a breaking change.
- Refactored `cli`, `auth-storage`, and `utils/oauth` to load provider modules via scoped dynamic `import()` calls.
- Removed top-level provider imports and barrel exports from `utils/oauth/index.ts`, streamlining oauth module loading.
- Consolidated OAuth symbol, type, and provider imports in coding-agent and tests to `@oh-my-pi/pi-ai/utils/oauth` modules.
- Defined `DEFAULT_LOCAL_TOKEN` locally in model-registry and removed its cross-package OAuth import usage.
- Added a new `loop.mode` enum setting and UI option entries for prompt, compact, and reset behaviors.
- Updated interactive mode's loop auto-submit flow to execute selected compact or reset actions before re-submitting the prompt.
- Registered a new `just.enabled` setting in the tools settings schema.
- Added loop-mode command handling in interactive mode, including enable/disable toggling, repeated auto-submission scheduling, and Escape-based cancellation.
- Propagated loop mode state to the status line via a renamed `mode` segment that now renders plan or loop status, and updated presets/theme assets for the new loop icon.
- Migrated persisted status-line segment usage from `plan_mode` to `mode` in configuration defaults and normalization so legacy settings continue to load.
- Renamed the built-in `grep` content-search tool to `search` across settings, schemas, and SDK exports.
- Switched execution wiring so `Task`, `Plan`, cursor, and shell mapping now invoke `search` instead of `grep`.
- Updated prompts, plan-mode docs, and example tool lists to replace `grep`/`ls` references with `search` guidance.
- Aligned `Grep*`/`grep` event, renderer, and hook types to `Search*`/`search` across runtime and tests.
- Documented and fixed `search` result rendering budget behavior and added internal-URL/path-list transcript notes.
Add explicit Basic auth credentials for SearXNG while preserving Bearer token fallback.
Keep optional SearXNG settings out of the TUI and allow empty RFC 7617 username/password fields.
- Added sanitizeText to edit renderer previews and diff rendering before line processing.
- Passed filePath into replaceTabs calls across edit previews, errors, and diff visualization paths.
- Grouped streaming edit strategies by file path and generated diff previews for each file, with a five-file preview cap.
- Updated patch and hashline preview generation to return per-file preview arrays instead of only the first file.
- Rendered multi-file streaming diffs with file headers in the edit tool UI and stored them when more than one preview is present.
- Removed `pi-natives` chunk language classifier modules and all core chunk subsystems (kind, state, render, edit, resolve).
- Removed chunk-mode CLI/read/edit entrypoints, including `read` command and chunk mode registration/prompt tooling.
- Removed chunk selectors from `read` and `grep` tools, switching behavior to raw/L-range handling.
- Fixed poll wait parsing to keep defaulting to `30s` when the provided value is empty.
- Session metadata now stores on-disk size bytes, populated from file stats when collecting sessions.
- The session selector metadata line now renders file size using formatBytes instead of message counts.
- Session test fixtures were updated with the new size property so they match the revised SessionInfo shape.
- 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`.
- Updated inline argument formatting in formatArgsInline to truncate key/value pairs by width and show ellipsis when values overflow.
- Fixed JSON-tree output to hide harness-internal INTENT_FIELD and __partialJson keys from top-level tool argument rendering.
- Fixed multiline scalar rendering and empty-structure display paths in renderJsonTreeLines after tree-prefix traversal changes.
- Added a regression test for tool argument coercion that preserves quoted edit arrays while stripping optional null fields.
- Updated footer branch-watcher initialization to clear cached branch state when resolving git head fails.
- Set the report_tool_issue tool definition to non-strict mode for looser argument handling.
- Added `CodeFrameMarker` and `formatCodeFrameLine()` to centralize code-frame gutter formatting.
- Extended diff rendering to preserve `|` and `│` separators, aligning gutter markers and line numbers.
- Reworked AST, grep, hashline, Vim, and diff renderers to use shared line formatting with computed `lineNumberWidth`.
- Updated atom editing flow and tests, including `resolveAtomEntryPaths` migration and new loc-based/edge-case coverage.
- Adjusted benchmark runner early-stop configuration by passing `buildEarlyStop` through prompt collection.
- Added `openai` and `openai-codex` as image providers and let `providers.image=auto` prefer GPT images.
- Updated settings, selector, and SDK wiring so OpenAI image providers pass through `setPreferredImageProvider`.
- Replaced Gemini-only image tooling with `image-gen` and added OpenAI/Codex hosted-image execution with SSE parsing.
- Added image-gen and handoff tests, including final-yield no-compaction regression and OpenAI payload/header assertions.
- Expanded hashline and chunk bigram tables to 647 entries and moved chunk checksums to a 40-item namespace.
- Changed hashline anchors from `LINE#ID`/`:` to concatenated `LINEID`\t forms across parsing and tool outputs.
- Removed line-number padding and routed diff/read/grep/renderer output through raw numbers, tabs, and `toDisplayLine` formatting.
- Renamed atom ops to `pre`/`post`, removed `ins`, and updated schemas, prompts, and tests for new insertion behavior.
Two regressions from 33dfce738:
1. selector-controller.ts imported nonexistent clearPluginRootsAndCaches
(was clearClaudePluginRootsCache). The previous commit collapsed the
inline closure that invalidated fs caches for plugin JSON files into
a direct function reference that doesn't exist. Restored the original
closure with its fs cache invalidation logic.
2. scrollToSelectedEntry() snapped oversized entries back to their top
on every PgDn/PgUp, defeating the line-scroll fallback. The condition
'entryTop < scrollOffset' fires whenever the user pages down within
a tall entry. Fixed: only snap when the viewport has no overlap with
the entry (completely above or completely below it).
- Replace `ReturnType<typeof this.ctx.ui.showOverlay>` with concrete
`OverlayHandle` type from @oh-my-pi/pi-tui
- Remove `as any` casts and redundant `as SessionMessageEntry` in
#loadTranscript; discriminated union narrowing on `entry.type` and
`msg.role` is sufficient
- Add missing `replaceTabs()` on collapsed user/developer preview text,
matching every other collapsed render path
- Added helper utilities in the edit renderer to parse partial JSON fragments and extract the `path` field.
- Used the extracted path as a fallback when resolving the edit target file, enabling partial streamed edit calls to show the path.
- Built and stored the render context before call rendering, and added a test covering partial JSON edit path rendering.