- Replaced ad-hoc ANSI/VT stripping regexes with `stripVTControlCharacters` in status text handling and related tests.
- Updated status footer rendering to truncate using `truncateToWidth` and visible width after VT stripping.
- Extended tui cursor handling and rendering to strip markers from all lines and fit repaint/append-tail lines to width.
- Expanded deterministic render tests with overlay-aware assertions and recorded the truncation/cursor-marker behavior in changelogs.
- Added a shared `interruptHint()` utility in the modes shared module to generate the interrupt suffix with themed bracket glyphs.
- Replaced hardcoded working-message interrupt text in interactive and event controllers with calls to `interruptHint()`.
- Updated working-message rendering to recognize and strip the new themed hint when applying shimmer styling.
- 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
- Extracted git operations from ControlledGit class into centralized utils/git module with 1276 lines of typed command wrappers.
- Replaced dependency injection of ControlledGit instances with direct cwd string parameters across commit agent tools and workflows.
- Migrated all git command execution from inline shell calls and custom helpers to structured git module API (diff, status, branch, worktree, patch, etc.).
- Removed ControlledGit class, operations.ts, and helper functions (findGitHeadPath, mergeStdoutStderr, joinPatch) now provided by git module.
- Exported git utilities from main package entry point for extension and plugin use.
- Consolidated @oh-my-pi/pi-utils subpath imports into single package root import across 100+ files.
- Moved tryParseJson utility from local web scrapers module to @oh-my-pi/pi-utils package for centralized JSON parsing.
- Renamed loadSkillsFromDir to scanSkillsFromDir and refactored skill discovery to use fs.promises.readdir instead of glob-based approach.
- Replaced custom parseJSON with tryParseJson across discovery modules for consistent error handling.
- Removed emitCustomToolSessionEvent method and cleanupSshResources function, consolidating shutdown logic into dispose method.
- Updated glob pattern construction to use GlobBuilder with literal_separator(true) for improved path handling.