- Remove redundant definedness, null, and type checks across test suites in multiple packages.
- Clean up unused assertions, metadata tests, and obsolete test cases.
- Add good versus bad test filter guidelines and requirements to project documentation.
- Introduced the `allowCreateOverwrite` option to permit `op: "create"` to replace existing files.
- Enabled `allowCreateOverwrite` specifically for the JSON-based `patch` edit mode to support full-file restructures.
- Maintained the strict non-overwriting behavior for Codex `apply_patch` envelope-based file additions.
- Configured patch diff previews to respect the configured overwrite permission during streaming.
- Fixed an issue where stopping a multi-file patch application early skipped flushing the active LSP writethrough batch.
The apply_patch language documents `*** Add File` and `*** Move to` as
strictly non-overwriting (create / rename), but the fs-level create and
rename paths in applyNormalizedPatch wrote through to the resolved target
without checking whether it already existed. Existing destinations were
silently replaced, and in the rename case the source was also deleted.
The multi-file executeApplyPatchPerFile aggregator caught each per-file
exception, appended an error entry, and kept iterating. Later files
still ran against an inconsistent post-state, and the aggregate result
had no top-level isError — so a mixed partial application looked like a
successful edit to the agent loop.
Changes:
- Add fs.exists guards before the create write and before the rename
write/delete in packages/coding-agent/src/edit/modes/patch.ts. Both
reject with ApplyPatchError before any side effect.
- Make executeApplyPatchPerFile in packages/coding-agent/src/edit/index.ts
stop at the first per-file failure, list applied vs. skipped files in
the aggregate text, and propagate isError, matching executeSinglePathEntries.
- Rename the two apply-patch scenario fixtures (010_move_..., 011_add_...)
that pinned the buggy overwrite behavior to _rejects_ variants, and
flip their expected/ trees so source and pre-existing destination
remain byte-identical after the rejected apply.
- Cover both failure modes with new regressions in
packages/coding-agent/test/core/apply-patch.test.ts and a new
packages/coding-agent/test/core/apply-patch-multi-file.test.ts.
Fixes#4074
Batch migration of 13 fs.rmSync calls to removeSyncWithRetries across:
- core/apply-patch.test.ts (4 calls)
- bash-executor.test.ts (4 calls)
- tools.test.ts (2 calls)
- compaction-hooks.test.ts (1 call)
- compaction-thinking-model.test.ts (2 calls)
Also exports removeSyncWithRetries from @oh-my-pi/pi-utils as a
standalone function for tests that manage their own temp dirs.
All tests pass: 139 pass, 0 fail across the 5 migrated files.
Slots a new "apply_patch" variant alongside the existing edit modes
(replace, patch, hashline, chunk, vim). The mode accepts a single input
string containing a Codex *** Begin Patch / *** End Patch envelope,
parses it with a new lenient parser (heredoc-tolerant), and fans each
file-op out to the existing executePatchSingle so LSP writethrough,
plan-mode guards, fs-cache invalidation and diagnostics are shared
with the patch mode.
Exposes both tool shapes from the spec: the JSON function-tool variant
(§1.2, {input: string}) and the OpenAI custom-tool / Lark-grammar
"freeform" variant (§1.1, raw patch string). The edit tool advertises
a Lark grammar via customFormat and a wire name via customWireName;
openai-responses emits it as a grammar-constrained custom tool when a
model opts in with applyPatchToolType: "freeform" in models.json.
custom_tool_call / custom_tool_call_output are plumbed end-to-end
through the shared responses code (emission, streaming, history
replay), and the agent-loop dispatcher matches tool calls by either
name or customWireName so returned calls route correctly.
Also threads preview/diff rendering for apply_patch through the TUI
(tool-execution + edit renderer) so streaming patches show per-file
diffs like the other edit modes.
Default edit mode is unchanged (hashline); opt in via edit.mode or
PI_EDIT_VARIANT=apply_patch.
- 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.
- Added persistent shell session support for bash tool with environment variable preservation across commands.
- Added shellForceBasic setting to force bash/sh even if user's default shell is different (default: true).
- Added OMP_SHELL_PERSIST environment variable to control persistent shell behavior (set to 0 to disable).
- Restructured system prompt with coordinator-specific guidance for parallel task delegation.
- Removed Prettier configuration files (.prettierignore and .prettierrc) and migrated formatting to Biome.
- Updated Biome configuration from version 2.3.11 to 2.3.12 and changed arrowParentheses rule from 'always' to 'asNeeded'.
- Pinned @biomejs/biome dependency to exact version 2.3.12 in package.json and bun.lock.
- Applied consistent arrow function formatting across 489 files by removing unnecessary parentheses around single parameters.
- Removed blank lines after comment blocks and reorganized imports for consistency across the codebase.
- Converted named imports from node modules (fs, path, os) to namespace imports across all packages.
- Extended extension loader error handling with isEacces and hasFsCode type guards.
- Converted readdirSync, readFileSync, and statSync to async readdir, readFile, stat across skills and agent discovery.
- Made scanDirectoryForSkills async and refactored custom directory scanning to use Promise.all for concurrent processing.
- Updated agent discovery to use fs/promises for async file reading and refactored helper patterns.
- Added AgentParsingError exception class for better error handling during agent parsing.
- Added filesystem error type guards (isEnoent, isEacces, isPerm, etc.) to pi-utils for safe error checking.
- Added color manipulation utilities to pi-utils for accessibility features.
- Added color-blind mode setting to settings manager.
- Migrated plugins, settings, and config modules from sync to async file operations.
- Updated error handling to use new pi-utils type guards for type-safe checking.
- Added tsconfig.publish.json files to all packages with optimized publish-time configuration.
- Updated all package.json scripts with prepublishOnly hooks for correct type checking during publish.
- Added @oh-my-pi/omp-stats path mappings to root tsconfig.json for consistent imports.
- Added WASM generation script for photon module and integrated into install:dev script.
- converted relative imports to path aliases ($c/*, $ai/*, $tui/*, etc.) across all packages
- added per-package tsconfig.json with complete path mappings for runtime resolution
- set importModuleSpecifier to non-relative for IDE auto-import preferences
- updated dev script to run from monorepo root for consistent path resolution
- Added artifact storage system with artifact:// URL protocol for truncated outputs.
- Added structured output metadata system with OutputMetaBuilder for consistent notices.
- Added standardized tool error types (ToolError, MultiError, ToolAbortError).
- Updated all tools to use structured metadata instead of inline notices.
- Removed activeForm field from TodoItem interface and simplified todo display logic.
- Converted dynamic imports to static imports in installer and exa tools.
- Renamed task parameter from vars to args throughout task tool interface.
- Simplified task template validation by removing strict placeholder requirements.
- Enhanced patch applicator with fallback variant generation and improved fuzzy matching.
- Added support for ellipsis placeholders, top-of-file anchors, and comment-prefix normalization.
- Renamed operation and moveTo parameters to op and rename across patch tool interfaces.
- Added batch processing system to benchmark runner for parallel task execution.
- Added comprehensive benchmark reports for Claude Haiku and GPT-5.1-codex-mini models.
- Refactored edit tool implementation with modular patch architecture.
- Moved edit tool implementation from edit/ to patch/ module.
- Updated import paths for EditToolDetails across core modules.
- Enhanced patch parsing with unified diff and Codex-style patch support.
- Improved fuzzy matching algorithms for more robust text location.