- Added support for writing to archive entries using `archive.ext:path/inside/archive` syntax for .tar, .tar.gz, .tgz, and .zip formats.
- Added ability to create new archives automatically when writing to non-existent archive subpaths with nested directory support.
- Implemented archive path resolution and validation with fallback to plain file writes for non-archive filenames.
- Added comprehensive test coverage for archive write operations including entry updates, archive creation, and fallback behavior.
- Removed 3 test cases from gh.test.ts that relied on implementation details and external state.
- Removed unused helper functions getCurrentHeadSha() and GhToolDetails import.
- Updated test assertions to use path.resolve() and corrected expected remote name from fork-contrib to forksrc.
- Reformatted else blocks in shell.rs for consistency.
- Replaced Python-based markitdown CLI with native markit-ai library for document and notebook conversion.
- Added support for converting Jupyter notebooks (.ipynb) to markdown via markit-ai integration.
- Created markit utility module with file/buffer conversion wrappers and standardized error handling.
- Removed markitdown from Python tools manager and eliminated external CLI dependency.
- Updated fetch, read, and scraper tools to use new markit conversion API across codebase.
- Added test coverage for ipynb file conversion through markit utility.
- Replaced blocking Tokio worker with non-blocking async I/O for pipe reading to prevent stalling the runtime when child processes keep pipes open.
- Refactored background job termination to use process group and process tree APIs instead of deprecated signal parsing, improving reliability across Unix and Windows.
- Added non-blocking pipe registration and fcntl-based flag management for Unix platforms to enable efficient async I/O without blocking workers.
- Added test case verifying read_output cancellation before pipe EOF to ensure proper cleanup behavior.
- Added archive reading support for .tar, .tar.gz, .tgz, and .zip files with virtual subpath syntax (archive.ext:path/inside/archive).
- Added archive listing and subdirectory navigation capabilities to explore archive contents without extraction.
- Added /tools slash command to display visible agent tools and their capabilities.
- Implemented ArchiveReader module with openArchive(), parseArchivePathCandidates(), and archive content extraction methods.
- Added fflate 0.8.2 dependency for archive decompression support.
- Added comprehensive test coverage for TAR, TAR.GZ, TGZ, and ZIP archive reading with fixture generation utilities.
- Added `/tools` slash command to display agent-visible tools in interactive sessions.
- Added `handleToolsCommand()` method to InteractiveMode to delegate tools display to command controller.
- Added `buildToolsMarkdown()` utility function to generate formatted markdown table of available tools.
- Refactored `showMarkdownPanel()` helper to reduce duplication in markdown display logic across commands.
- abortableSleep used Bun.sleep which vitest fake timers do not intercept;
switch to setTimeout via Promise.withResolvers so vi.useFakeTimers() +
vi.advanceTimersByTime() work correctly in the polling loop tests
- getCurrentHeadSha() and GhRunWatchTool session cwd used a hardcoded
/work/pi path; replace with import.meta.dir so the tests resolve the
real repo HEAD on any machine
- add timeout-minutes: 30 to the CI test job as a safety net against
future hangs blocking release runs
- Fixed artifact storage for non-persistent sessions to use in-memory fallback instead of returning undefined, enabling proper spill truncation for all session types.
- Added in-memory artifact map and counter to SessionManager for fallback storage when file-based ArtifactManager is unavailable.
- Updated saveArtifact() JSDoc to reflect new behavior of returning artifact IDs for all sessions.
- Enhanced `gh_run_watch` tool call rendering to display animated spinner status and target description (run ID, branch, or current HEAD) with improved visual hierarchy.
- Refactored renderer to use `formatStatusIcon` helper for consistent status display across spinner frames.
- Added gh-renderer.ts module with GitHub Actions workflow visualization for terminal output.
- Enhanced gh_pr_view tool to fetch and display inline review comments alongside pull request reviews.
- Improved gh_run_watch tool output with structured job state tracking and failed log formatting.
- Fixed gh_run_watch to resolve explicit branch watches against GitHub API branch head instead of local HEAD.
- Fixed gh_* tool outputs to spill full large results to artifacts instead of pre-truncating.
- Standardized trailing newlines across 100+ prompt template files for POSIX compliance.
- Added gh_pr_checkout tool to check out GitHub pull requests into git worktrees with branch metadata.
- Added gh_pr_push tool to push checked-out pull request branches to source fork with force-with-lease support.
- Implemented 15+ git helper functions for worktree, branch, and remote management operations.
- Extended GhPrViewData interface with headRefOid, headRepository, isCrossRepository, and maintainerCanModify fields.
- Added comprehensive integration tests for gh_pr_checkout and gh_pr_push tools with fixture setup and cleanup.
sanitizeRehydratedOpenAIResponsesAssistantMessage now removes the
assistant providerPayload for Responses-family messages, not just the
stale thinkingSignature. After rehydration the native replay snapshot
belongs to a previous live provider connection and replaying it on a
warmed session causes 401 rejections from GitHub Copilot.
User/developer providerPayload is preserved by the caller since it
carries durable compaction and preserved history needed for valid cold
request reconstruction.
Fixes#592
* fix(ai): update spoofed Gemini CLI User-Agent to v0.35.3 format
Gemini CLI v0.35+ changed its User-Agent format:
- Dropped 'google-api-nodejs-client/10.5.0' suffix
- Added surface field (third param in parens)
- New format: GeminiCLI/VERSION/MODEL (PLATFORM; ARCH; SURFACE)
The stale v0.34.0 UA was contributing to google-gemini-cli/gemini-3.1-pro-preview
being rejected, alongside Google's new abuse detection for third-party CCA usage
(google-gemini/gemini-cli#22970).
Verified: model responds successfully with updated UA.
* feat(scripts): add spoofed version drift checker
Fetches latest stable release from google-gemini/gemini-cli GitHub
releases and compares against the hardcoded version in the provider.
bun check-spoofed-versions # report drift, exit 1 on mismatch
bun check-spoofed-versions --update # apply version bump in-place
Extensible for additional spoofed tools (Antigravity, Copilot headers).
- Replaced truncation with line wrapping for diff output in the edit tool renderer.
- Added `wrapEditRendererLine` to preserve gutter markers and line numbers on continuation lines.
Fixes#578
- Applied `disabledProviders` setting to `getAvailable()` and `getDiscoverableProviders()` so `--list-models` and `/model` hide models from disabled providers.
- Initialized settings before model refresh in the `--list-models` code path.
- Added tests verifying disabled providers are excluded from both methods.
Fixes#588
- Added `thinkingSignature` field to thinking content blocks to preserve the original reasoning field name (e.g., `reasoning_text`, `reasoning_content`) for accurate follow-up requests.
- Enhanced thinking block handling to track and distinguish between different reasoning field types, enabling proper field name preservation across multiple conversation turns.
- Updated `appendThinking` function to accept optional signature parameter and conditionally create new thinking blocks when signature changes.
- Added test case validating that streamed reasoning field names are preserved for follow-up requests.
- Added first-event timeout detection for streaming responses to prevent stuck requests and enable faster recovery from stream stalls.
- Added PI_STREAM_FIRST_EVENT_TIMEOUT_MS environment variable to configure first-event timeout behavior independently from idle timeouts.
- Fixed Anthropic stream timeout errors to be properly retried with first-event recognition, distinguishing first-event from idle timeouts.
- Enhanced idle-iterator utility with FirstEventWatchdog mechanism and markFirstStreamEvent wrapper for unified timeout handling across OpenAI, Azure OpenAI, and Anthropic providers.
- Removed code_search tool and all related Exa API integration from web search module.
- Deleted code-search.ts implementation including CodeSearchResponse types and executeCodeSearch() function.
- Updated getSearchTools() to return only webSearchCustomTool, removing dual-tool support.
- Removed code_search tool documentation from README and prompt files.
* fix(ai): Added developer role support for reasoning-enabled OpenAI models
- Added supportsDeveloperRole function to check developer role support based on provider and base URL.
- Updated system prompt role logic to use developer role only when supported.
- Improved reasoning content handling with provider-specific role enforcement.
* feat(ai): Added developer role support for reasoning models with provider fallback
- Exported supportsDeveloperRole function to enable cross-provider usage.
- Updated Azure provider to check developer role support before assignment.
- Implemented system role fallback when developer role is unsupported.
- Fixed role assignment to use developer role when supported.
* feat(ai): added support for Azure OpenAI inference endpoint
- Allow Azure OpenAI Inference endpoint (azure.com/openai) via `includes()` matching on baseUrl, enabling broader Azure-compatibility.
* test: add test file for developer role handler in OpenAI responses provider
* fix(ai): fixed developer role validation to reject custom base URLs
- Changed supportsDeveloperRole to use base URL pattern matching instead of provider short-circuit.
- Added tests to verify developer role support returns false for custom proxy base URLs.
* fix(ai): Updated GitHub Copilot endpoint detection
- Expands GitHub Copilot endpoint detection to support multiple GitHub Copilot enterprise and copilot-api domains.
- Adds 3 new test scenarios wrapping unsupported/correct patterns for github-copilot provider endpoints.
* chore(ci): Add *.tmp pattern in OS section
- Adds *.tmp to ignore all temporary files with .tmp extension
- Groups with other OS temp files (.DS_Store)
* docs(ai): Consolidate changelog entry for developer role fix
* feat(ai/providers): Added baseUrl resolution support across OpenAI providers
- Resolve baseUrl before buildParams calls in azure-openai-responses.ts for correct system role logic.
- Add baseUrl resolution to openai-responses.ts and openai-completions.ts.
- Add optional resolvedBaseUrl to getCompat function for better compatibility detection.
- Update supportsDeveloperRole to accept both Model objects and baseUrl strings.
listInstalledPlugins() was marking user-scope entries as shadowedBy:
"project" based on plugin ID presence in the project registry alone.
A disabled project copy (enabled: false) is not active in discovery, so
the user copy is the effective install and must not appear shadowed.
activeProjectIds now only includes project plugins where the first entry
does not have enabled: false.
omp plugin ... --scope project was rejected by the strict CLI parser
before reaching any handler, making the feature inaccessible via the
omp plugin entrypoint. Declaring scope in static flags and forwarding
it to PluginCommandArgs.flags lets the CLI framework accept and route it.
When a plugin is installed in both user and project scope, the selector
now shows separate scoped entries (e.g. 'plugin-name@1.0 [project]' and
'plugin-name@1.0 [user]') and forwards the selected scope to
uninstallPlugin(), preventing the disambiguation error introduced when
dual-scope support was added.