- Added `/rename <title>` slash command to set explicit session names and update header/tab titles.
- Added `session_name` status segment with hash-derived accent color for session titles.
- Fixed shell execution failure sanitization to preserve all `execResult` fields after redacting stderr.
- Fixed tool execution completion output to pass original `toolResult` text instead of sanitized `content`.
- Add /rename <title> slash command to set an explicit session name,
updating the session header, terminal tab title, and status line
- Add session_name status segment: displays the session name on the
right side of the status bar with a stable djb2-hash-derived accent
color unique to each name; shown in all presets when a name is set
- Add setSessionName source tracking ('user' vs 'auto'): auto-generated
titles are silently ignored once the user has explicitly set a name,
preventing the async title generation from overwriting a /rename
- Sanitize session names at storage time: strip C0/C1 control characters
(including ANSI ESC) via static #sanitizeName before storing, blocking
escape sequence injection into the TUI, terminal title, and session file
- Extend sanitizeStatusText to cover the full C0/C1 range as
defense-in-depth (superset of the previous \r\n\t-only strip)
- Use stored (sanitized) name for showStatus message and terminal title
in handleRenameCommand, not the raw user input
- Guard terminal title update in auto-title path via titleSource === 'auto'
so a user rename is never overwritten by a late-resolving LLM call
- Reset #titleSource in #newSessionSync so each new session starts fresh
- Thread source parameter through AgentSession.setSessionName wrapper;
extension API and RPC set_session_name treated as 'user' intent
Closes#658
- Added canonical model equivalence types, cache helpers, and registry APIs for provider variant lookup.
- Changed model resolution to apply canonical ID overrides/excludes with provider order before fallback matching.
- Added canonical and provider model views in list-models and selector UI with canonical sorting/persistence.
- Updated role/model persistence to store selectors while runtime now resolves concrete canonical-backed provider models.
- Document session name getter/setter methods in extensions.md
- Add stub methods to ExtensionProxy that throw if called before init
- Add delegating implementations to ExtensionProxyInit
- Wire up getSessionName and setSessionName in extension runtime
- Add method signatures to ExtensionContext interface and type
- Add getSessionName to session manager API
- Add getSessionName and setSessionName to all mode contexts:
- ACP agent
- Extension UI controller (also updates terminal title)
- Print mode
- RPC mode
- Fixed usage report generation to preserve partial data when parsing payloads are incomplete.
- Fixed planType resolution to fall back to raw `plan_type` when parsed planType is missing.
- Fixed usage metadata population to set accountId and keep the original raw payload when parsed raw output is absent.
- Fixed usage report rendering to label unlimited plans and display a clear `-- no limits` status line.
- agent-loop: sanitize text content in tool_execution result/partialResult
- ai/cursor: fix ANSI escape handling, add incomplete escape detection
- coding-agent/cursor: fix per-delta sanitization with tracked state
- print-mode: flush stderr before exit to prevent data loss
- add unit tests for bash execution clamp display line
- Add sanitizeText import to print-mode.ts
- Sanitize content.text before writing to stdout
- Prevents terminal control sequences from affecting user terminal
- Add defensive truncation in TUI to silently clip lines exceeding terminal width
- Fix BashExecutionComponent to use visibleWidth() instead of raw string length
- Prevents crash when bash output contains terminal control sequences
- 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.
- Migrated hash API calls from Bun.hash.xxHash64() to Bun.hash() across TypeScript packages for simplified hash generation.
- Consolidated mermaid cache failure tracking by replacing separate failed Set with null values in cache Map.
- Refactored schema-based child extraction in Rust by introducing promotion_fields tracking and schema_wrapper_child() helper function.
- Updated TypeScript configuration files with reformatted arrays and added compiler options for consistency.
- Extracted tab width resolution from pi-natives to pi-utils with EditorConfig caching support.
- Made tabWidth parameter required in native text functions (visibleWidth, truncateToWidth, wrapTextWithAnsi, sliceWithWidth, extractSegments).
- Removed process-wide tab width state management from pi-natives text module.
- Consolidated wrapper node promotion logic in chunk classification with abbreviated string representations.
- Removed path-clean and pathdiff dependencies from pi-natives.
- Updated all consuming packages to import tab width functions from pi-utils and pass explicit tabWidth parameters.
- Extracted language detection logic into dedicated module for reusability across LSP and theme subsystems.
- Unified extension-to-language mapping with dual identifiers (highlight and LSP) to eliminate duplication.
- Consolidated detectLanguageId and getLanguageFromPath into single source of truth in lang-from-path module.
Move live stats (tokens, tools, duration) from the header — which scrolls
above the TUI viewport for long transcripts — to a stable Text component
placed after the viewerContainer. Stats are updated in-place via setText()
so the diff algorithm sees changes near the bottom of rendered output,
avoiding the fullRender(true) trigger when firstChanged < viewportTop.
Previously every ~150ms progress update changed the header stats line,
which sat above the viewport for large transcripts. The TUI's safety
check (firstChanged < previousContentViewportTop) forced a full screen
clear and re-render each cycle. In multiplexers (tmux/zellij) this
produced visible repetitive scrolling because scrollback is preserved
across clears.
- Enhanced slash command handlers to return remaining text as prompt input instead of consuming input entirely.
- Updated slash command parser to recognize both whitespace and colon (`:`) as command argument separators.
- Modified executeBuiltinSlashCommand return type to support string (remaining text) or boolean (consumed/not matched).
- Updated input controller to handle remaining text from slash commands and use it as prompt input.
- Extracted image metadata detection and MIME type utilities to @oh-my-pi/pi-utils package for shared use across projects.
- Consolidated image-input.ts and mime.ts modules into image-loading.ts with simplified API removing redundant metadata parameters.
- Updated all import paths across coding-agent to use readImageMetadata from @oh-my-pi/pi-utils instead of local utilities.
- Added peek-file utility module to @oh-my-pi/pi-utils with buffer pooling for efficient file header reading.
- Added Auto QA tool (`report_tool_issue`) for automated tracking of unexpected tool behavior with environment variable and setting support.
- Added Python tool environment warmup on first execution to ensure prelude helpers are available before use.
- Fixed Python prelude introspection to respect execution timeout and signal options, preventing hangs.
- Refactored prelude documentation caching and loading logic into reusable helper functions with test environment awareness.
- Enhanced kernel introspection with optional timeout and signal parameters for better execution control.
- Added system prompt guidance to encourage agents to report tool issues via Auto QA when available.
- Added real-time LSP server status updates in welcome banner when background warmup completes.
- Changed welcome banner status icon from warning to muted pending symbol for improved visual clarity.
- Extracted LSP server conversion logic into dedicated helper methods for better maintainability.
- Added comprehensive test coverage for interactive mode LSP startup welcome banner updates.
- Refactored logger.time() API to accept function references and arguments separately instead of wrapped callbacks.
- Replaced RingBuffer-based timing with wall-clock markers and async span tracking for improved timing accuracy.
- Updated 20+ call sites across executor, kernel, main, and tools modules to use new logger.time() signature.
- Removed parsePath() helper function and inlined path.split() calls in settings module.
- Added test case verifying model selection without auth validation during startup.
- Added asynchronous LSP server discovery and warmup at startup via `discoverStartupLspServers()` function.
- Added LSP startup event channel (`lsp:startup`) for real-time server status notifications during warmup.
- Added `LspStartupServerInfo` type to track LSP server status (connecting, ready, error) throughout lifecycle.
- Changed LSP server warmup from blocking synchronous operation to non-blocking background task.
- Refactored interactive mode to subscribe to LSP startup events and display real-time server status updates.
- Added multi-session support to ACP mode enabling session forking, resumption, and closure operations.
- Added session model state reporting and unstable_setSessionModel RPC command for direct model configuration.
- Added turn-level usage tracking and stable message ID tracking for assistant chunks in ACP responses.
- Added Settings.cloneForCwd() method and ExtensionRunner.getFlagValues() for configuration isolation across sessions.
- Fixed ACP session cleanup to properly cancel in-flight prompts and dispose resources on disconnect.
- Refactored AcpAgent to manage multiple concurrent sessions with per-session lifecycle instead of single session.
- Refactored chunk tree initialization to use explicit prologue/epilogue byte boundaries instead of None values.
- Extracted chunk resolution logic to use split_selector_crc_and_region() helper for improved code reuse.
- Reorganized package.json exports across multiple modules (autoresearch, cli, dap, edit, modes) for better API surface clarity.
- Updated test expectations for Go receiver method rendering and chunk selector formats to match refactored output.
- Consolidated notebook conversion logic and removed unused _createErrorToolResult helper function.
- Improved leading trivia preservation in chunk edits by detecting and maintaining line prefix whitespace.
- Added host tool execution framework with HostTool, HostToolContext, and host_tool() factory for custom tool integration.
- Added RpcConcurrencyError exception and _PromptLifecycleCoordinator to enforce single-flight constraint on prompt lifecycle methods.
- Enhanced JSON parsing with 10 validation helpers and enum frozensets for safe field extraction with detailed error messages.
- Replaced manual event/error list management with _BoundedHistory for bounded-size history with offset tracking.
- Added deep JSON cloning to prevent external mutations of stored payloads and improved UTF-8 error handling in subprocess stderr.
- Added custom_tools parameter to RpcClient and set_custom_tools() method for runtime tool registration.
- Extracted prompt rendering and formatting utilities from coding-agent to centralized pi-utils package with new API surface (prompt.render, prompt.format, prompt.registerHelper).
- Migrated parseFrontmatter utility from coding-agent to pi-utils package; updated 8 files to import from @oh-my-pi/pi-utils.
- Removed 170-line prompt-format.ts module and consolidated 192 lines of Handlebars helper registrations into pi-utils prompt module.
- Updated 60+ files across coding-agent and typescript-edit-benchmark to use new prompt.render() and prompt.format() API from pi-utils.
- Simplified prompt-templates.ts by delegating core functionality to pi-utils while retaining custom helper registrations (jtdToTypeScript, jsonStringify, etc.).
- Added typed event listeners and granular event handling for all RPC notification types.
- Added set_todos RPC command and todoPhases session state field for todo phase management.
- Added RpcClient initialization parameters (thinking, tools, no_session, rpc_defaults) for startup configuration.
- Added install_headless_ui() method and todo management methods (get_todos, set_todos, clear_todos).
- Added TodoItem and TodoPhase dataclasses with parser functions for structured todo representation.
- Added RPC mode behavior: disables session title generation by default and resets workflow settings to built-in defaults.
- Reorganized edit tool from `patch/` to `edit/` directory with dedicated mode subdirectories (chunk, patch, hashline, replace).
- Replaced line-scoped edit operations with substring-based `find` parameter and added `replace_body` operation for preserving signatures.
- Added chunk focus modes (Expanded, Collapsed, Container) and focused rendering to display only touched chunks and adjacent siblings.
- Implemented notebook (ipynb) language support with virtual source conversion and cell-based chunk parsing.
- Enhanced chunk edit error messages with consistent checksum mismatch reporting and improved chunk selector auto-resolution.
- Extracted edit mode implementations into separate modules with improved helper functions and LSP integration for diagnostics.
- Fixed plan review previews to re-append at the chat tail on refresh, keeping them adjacent to the active selector instead of updating off-screen.
- Added comprehensive test coverage for plan review rendering behavior across multiple refresh cycles.
- Migrated native bindings from TypeScript wrappers to NAPI-RS generated modules with auto-generated type definitions and runtime enums.
- Replaced chunk tree API with stateful ChunkState class supporting render, edit, and resolve operations with improved error handling.
- Converted callback signatures to error-first pattern (error, result) for shell, PTY, glob, and grep operations.
- Introduced type-safe enums for MacOSAppearance, GrepOutputMode, KeyEventType, ImageFormat, and AstMatchStrictness replacing string literals.
- Refactored chunk tree implementation with dedicated modules for edit, indent, resolve, and state management with comprehensive validation.
- Moved clipboard utilities from native bindings to coding-agent package with improved OSC 52 and Termux compatibility.
- Added `anchorStyle` setting ("full", "kind", "bare") to control anchor name verbosity in chunk output.
- Changed anchor tag delimiters from `` to `[…]` and gutter separator from `│` to `|`.
- Changed edit response to render only changed hunks with context instead of the full chunk tree.
- 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.
Compaction and tool-output pruning can rewrite the session JSONL in
place, shrinking the file. When stat.size < bytesRead, the cache is
now invalidated and the file is re-read from scratch, preventing the
observer from getting stuck on a stale transcript.
Only advance bytesRead to the last complete newline-terminated line,
not to EOF. A partial trailing record (read during mid-write) stays
unconsumed and gets re-read on the next refresh, preventing permanent
entry loss from the transcript.