@oh-my-pi/pi-coding-agent 13.16.3 → 13.16.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [13.16.4] - 2026-03-28
|
|
6
|
+
### Changed
|
|
7
|
+
|
|
8
|
+
- Renamed hashline helper functions from `hlineref`/`hlinefull` to `href`/`hline` for brevity
|
|
9
|
+
- Simplified hashline edit location API: replaced separate `line` and `block` properties with unified `range` property accepting `{ pos, end }` for all range-based edits
|
|
10
|
+
- Updated hashline prompt documentation to reflect new `range` syntax and clarified editing guidelines
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Added detection for `kysely-codegen` generated files in auto-generated file guard
|
|
15
|
+
|
|
5
16
|
## [13.16.1] - 2026-03-27
|
|
6
17
|
|
|
7
18
|
### Added
|
|
@@ -17,6 +28,7 @@
|
|
|
17
28
|
- Updated grep tool description to remove ripgrep-specific implementation detail
|
|
18
29
|
|
|
19
30
|
## [13.16.0] - 2026-03-27
|
|
31
|
+
|
|
20
32
|
### Added
|
|
21
33
|
|
|
22
34
|
- Implemented root path alias: bare `/` in tool inputs now resolves to the session working directory instead of the filesystem root
|
|
@@ -36,6 +48,7 @@
|
|
|
36
48
|
- Added configurable `app.model.selectTemporary` keybinding for temporary model selection.
|
|
37
49
|
|
|
38
50
|
## [13.15.0] - 2026-03-23
|
|
51
|
+
|
|
39
52
|
### Breaking Changes
|
|
40
53
|
|
|
41
54
|
- Changed hashline edit schema from flat `op`/`pos`/`end`/`lines` fields to structured `loc`/`content` format with location-specific objects
|
|
@@ -162,10 +175,10 @@
|
|
|
162
175
|
- Fixed autoresearch logging to require durable ASI metadata (hypothesis, rollback_reason, next_action_hint) for every run including rollback context for discarded, crashed, and checks-failed experiments
|
|
163
176
|
- Fixed autoresearch logging to require durable ASI metadata for every run, including rollback context for discarded, crashed, and checks-failed experiments
|
|
164
177
|
|
|
165
|
-
|
|
166
178
|
### Fixed
|
|
167
179
|
|
|
168
180
|
- Fixed resumed and session-switched GitHub Copilot/OpenAI Responses conversations replaying stale assistant native history from older saved sessions by sanitizing persisted assistant replay metadata on rehydration and resetting provider session state across live session boundaries ([#505](https://github.com/can1357/oh-my-pi/issues/505))
|
|
181
|
+
|
|
169
182
|
## [13.14.0] - 2026-03-20
|
|
170
183
|
|
|
171
184
|
### Added
|
|
@@ -200,6 +213,7 @@
|
|
|
200
213
|
- Added `mcpServerName` and `mcpToolName` optional properties to custom tools for MCP server discovery and search metadata
|
|
201
214
|
|
|
202
215
|
## [13.13.1] - 2026-03-18
|
|
216
|
+
|
|
203
217
|
### Added
|
|
204
218
|
|
|
205
219
|
- Automatic deduplication of identical context files by content, keeping the closest (lowest depth) copy when duplicates are discovered
|
|
@@ -218,6 +232,7 @@
|
|
|
218
232
|
- Enhanced auto-generated marker detection to only scan leading header comments rather than entire file prefix, improving accuracy for files with generated markers in code
|
|
219
233
|
|
|
220
234
|
## [13.12.10] - 2026-03-17
|
|
235
|
+
|
|
221
236
|
### Added
|
|
222
237
|
|
|
223
238
|
- Added `args` field to ShellResult to capture the executed command
|
|
@@ -230,6 +245,7 @@
|
|
|
230
245
|
- Updated `run()` command documentation to clarify available ShellResult fields
|
|
231
246
|
|
|
232
247
|
## [13.12.9] - 2026-03-17
|
|
248
|
+
|
|
233
249
|
### Added
|
|
234
250
|
|
|
235
251
|
- Added `/session delete` command to delete current session with confirmation and return to session selector
|
|
@@ -274,6 +290,7 @@
|
|
|
274
290
|
- Fixed session directory resolution to correctly handle symlink-equivalent paths, ensuring aliased home and temp directories resolve to the same session storage location as their real targets
|
|
275
291
|
|
|
276
292
|
## [13.12.7] - 2026-03-16
|
|
293
|
+
|
|
277
294
|
### Changed
|
|
278
295
|
|
|
279
296
|
- Modified `getSelectedMCPToolNames()` to return only active MCP tools in non-discovery sessions, filtering by tool registry availability
|
|
@@ -285,6 +302,7 @@
|
|
|
285
302
|
- Fixed MCP tool selection tracking to properly distinguish between discovery-enabled and non-discovery sessions, preventing orphaned tool selections after manual deactivation
|
|
286
303
|
|
|
287
304
|
## [13.12.6] - 2026-03-15
|
|
305
|
+
|
|
288
306
|
### Changed
|
|
289
307
|
|
|
290
308
|
- Updated llama.cpp model discovery to read context window from the `/props` endpoint's `default_generation_settings.n_ctx` field instead of using hardcoded 128000 default
|
|
@@ -320,6 +338,7 @@
|
|
|
320
338
|
- Fixed automatic migration of legacy session directories to new `-tmp-` prefixed naming scheme for temp-root sessions
|
|
321
339
|
|
|
322
340
|
## [13.12.4] - 2026-03-15
|
|
341
|
+
|
|
323
342
|
### Added
|
|
324
343
|
|
|
325
344
|
- Exposed `settings` instance in `CustomToolContext` for session-specific configuration access
|
|
@@ -357,6 +376,7 @@
|
|
|
357
376
|
- Fixed skill loading to properly respect disabled skill names when loading from custom directories
|
|
358
377
|
|
|
359
378
|
## [13.12.1] - 2026-03-15
|
|
379
|
+
|
|
360
380
|
### Added
|
|
361
381
|
|
|
362
382
|
- Support for move-only operations that preserve exact bytes including binary files
|
|
@@ -396,7 +416,7 @@
|
|
|
396
416
|
- Moved LSP settings (lsp.enabled, lsp.formatOnWrite, lsp.diagnosticsOnWrite, lsp.diagnosticsOnEdit) to the Editing tab
|
|
397
417
|
- Moved bash interceptor settings to the Editing tab
|
|
398
418
|
- Moved Python settings (python.toolMode, python.kernelMode, python.sharedGateway) to the Editing tab
|
|
399
|
-
- Moved task delegation settings (task.isolation
|
|
419
|
+
- Moved task delegation settings (task.isolation.\*, task.eager, task.maxConcurrency, task.maxRecursionDepth) to the Tasks tab
|
|
400
420
|
- Moved skill and command settings to the Tasks tab
|
|
401
421
|
- Moved provider selection settings (providers.webSearch, providers.codeSearch, providers.image, etc.) to the Providers tab
|
|
402
422
|
- Moved Exa settings to the Providers tab
|
|
@@ -452,6 +472,7 @@
|
|
|
452
472
|
- Fixed line number parsing in compact diff preview to handle variable-width line number fields with leading whitespace
|
|
453
473
|
|
|
454
474
|
## [13.11.0] - 2026-03-12
|
|
475
|
+
|
|
455
476
|
### Added
|
|
456
477
|
|
|
457
478
|
- Added Parallel as a web search provider with support for fast and research modes
|
|
@@ -494,6 +515,7 @@
|
|
|
494
515
|
- Per-role `modelRoles` thinking selectors now propagate through commit/title helper model selection, legacy commit analysis, and agentic commit sessions while preserving default thinking inheritance when no role override is configured
|
|
495
516
|
|
|
496
517
|
## [13.10.1] - 2026-03-10
|
|
518
|
+
|
|
497
519
|
### Added
|
|
498
520
|
|
|
499
521
|
- Exported `submitInteractiveInput()` function for programmatic submission of user input in interactive mode
|
|
@@ -501,15 +523,19 @@
|
|
|
501
523
|
- Added reactive 401/403 retry with automatic token refresh on HTTP MCP transports
|
|
502
524
|
- Added `refreshMCPOAuthToken()` for standard OAuth 2.0 refresh_token grants
|
|
503
525
|
- Persisted `tokenUrl`, `clientId`, and `clientSecret` in MCP auth config for cross-session token refresh
|
|
526
|
+
|
|
504
527
|
### Fixed
|
|
528
|
+
|
|
505
529
|
- Respected `PI_CONFIG_DIR` when discovering native user config paths for slash commands and related config directories ([#349](https://github.com/can1357/oh-my-pi/issues/349))
|
|
506
530
|
|
|
507
531
|
## [13.10.0] - 2026-03-10
|
|
532
|
+
|
|
508
533
|
### Fixed
|
|
509
534
|
|
|
510
535
|
- Preserved text signature metadata (id and phase) when building OpenAI native history during session compaction
|
|
511
536
|
|
|
512
537
|
## [13.9.16] - 2026-03-10
|
|
538
|
+
|
|
513
539
|
### Breaking Changes
|
|
514
540
|
|
|
515
541
|
- Web search tool no longer accepts `provider` parameter in tool calls; use internal provider resolution instead
|
|
@@ -548,6 +574,7 @@
|
|
|
548
574
|
- Fixed model selector to show discovery status messages when provider has no models
|
|
549
575
|
|
|
550
576
|
## [13.9.15] - 2026-03-10
|
|
577
|
+
|
|
551
578
|
### Added
|
|
552
579
|
|
|
553
580
|
- Added `ensureLoadingAnimation()` method to manage loading animation lifecycle and prevent duplicate spinners
|
|
@@ -558,6 +585,7 @@
|
|
|
558
585
|
- Updated `showError()` to properly clean up loading animation state when errors occur
|
|
559
586
|
|
|
560
587
|
## [13.9.12] - 2026-03-09
|
|
588
|
+
|
|
561
589
|
### Added
|
|
562
590
|
|
|
563
591
|
- Added Tavily as a supported web search provider with `TAVILY_API_KEY` credential discovery and provider fallback support
|
|
@@ -575,6 +603,7 @@
|
|
|
575
603
|
- Canonicalized bash executor working directories before handing them to brush so `pwd` stays aligned with canonical Git worktree paths in symlinked workspaces
|
|
576
604
|
|
|
577
605
|
## [13.9.10] - 2026-03-08
|
|
606
|
+
|
|
578
607
|
### Added
|
|
579
608
|
|
|
580
609
|
- Added `env` parameter to bash tool to pass environment variables safely without shell re-parsing, preventing quote and special character bugs with multiline or untrusted values
|
|
@@ -586,6 +615,7 @@
|
|
|
586
615
|
- Changed bash tool to display environment variable assignments in command preview when `env` parameter is used
|
|
587
616
|
|
|
588
617
|
## [13.9.8] - 2026-03-08
|
|
618
|
+
|
|
589
619
|
### Added
|
|
590
620
|
|
|
591
621
|
- Added docs.rs scraper for extracting Rust crate documentation from rustdoc JSON, including support for modules, functions, structs, traits, enums, and other Rust items with caching
|
|
@@ -620,6 +650,7 @@
|
|
|
620
650
|
- Updated `grep` tool to combine glob patterns from `path` and `glob` parameters instead of throwing an error when both are provided
|
|
621
651
|
|
|
622
652
|
## [13.9.4] - 2026-03-07
|
|
653
|
+
|
|
623
654
|
### Added
|
|
624
655
|
|
|
625
656
|
- Automatic detection of Ollama model capabilities including reasoning/thinking support and vision input via the `/api/show` endpoint
|
|
@@ -708,6 +739,7 @@
|
|
|
708
739
|
- Auto-corrected off-by-one range start errors in hashline edits that would duplicate preceding lines
|
|
709
740
|
|
|
710
741
|
## [13.9.0] - 2026-03-05
|
|
742
|
+
|
|
711
743
|
### Added
|
|
712
744
|
|
|
713
745
|
- Added `read.defaultLimit` setting to configure default number of lines returned by read tool when no limit is specified (default: 300 lines)
|
|
@@ -736,6 +768,7 @@
|
|
|
736
768
|
- Fixed provider session state not being cleared when branching or navigating tree history, preventing resource leaks with codex provider sessions
|
|
737
769
|
|
|
738
770
|
## [13.8.0] - 2026-03-04
|
|
771
|
+
|
|
739
772
|
### Added
|
|
740
773
|
|
|
741
774
|
- Added `buildCompactHashlineDiffPreview()` function to generate compact diff previews for model-visible tool responses, collapsing long unchanged runs and consecutive additions/removals to show edit shape without full file content
|
|
@@ -751,6 +784,7 @@
|
|
|
751
784
|
- Fixed `:thinking` suffix in `modelRoles` config values silently breaking model resolution (e.g., `slow: anthropic/claude-opus-4-6:high`) and being stripped on Ctrl+P role cycling
|
|
752
785
|
|
|
753
786
|
## [13.7.6] - 2026-03-04
|
|
787
|
+
|
|
754
788
|
### Added
|
|
755
789
|
|
|
756
790
|
- Exported `dedupeParseErrors` utility function to deduplicate parse error messages while preserving order
|
|
@@ -761,7 +795,9 @@
|
|
|
761
795
|
- Normalized parse error output in ast-grep to remove pattern-specific prefixes and show only file-level errors
|
|
762
796
|
|
|
763
797
|
## [13.7.4] - 2026-03-04
|
|
798
|
+
|
|
764
799
|
### Added
|
|
800
|
+
|
|
765
801
|
- Added `fetch.useKagiSummarizer` setting to toggle Kagi Universal Summarizer usage in the fetch tool.
|
|
766
802
|
|
|
767
803
|
### Fixed
|
|
@@ -781,7 +817,7 @@
|
|
|
781
817
|
### Changed
|
|
782
818
|
|
|
783
819
|
- Updated hashline prompt documentation with clearer operation syntax and improved examples showing full edit structure with path and edits array
|
|
784
|
-
- Refactored `
|
|
820
|
+
- Refactored `href` Handlebars helper to return JSON-quoted strings for safer embedding in JSON blocks within prompts
|
|
785
821
|
- Improved `hashlineParseText` to correctly preserve blank lines and trailing empty strings in array input while stripping trailing newlines from string input
|
|
786
822
|
- Optimized duplicate line detection in range replacements to use trimmed comparison, reducing false positives from whitespace differences
|
|
787
823
|
- Refactored Kagi search provider to use shared Kagi API utilities from `web/kagi` module
|
|
@@ -792,6 +828,7 @@
|
|
|
792
828
|
- Fixed `isEscapedTabAutocorrectEnabled` environment variable parsing to use switch statement for clearer logic and consistent default behavior
|
|
793
829
|
|
|
794
830
|
## [13.7.2] - 2026-03-04
|
|
831
|
+
|
|
795
832
|
### Added
|
|
796
833
|
|
|
797
834
|
- Added support for direct OAuth provider login via `/login <provider>` command (e.g., `/login kagi`)
|
|
@@ -808,6 +845,7 @@
|
|
|
808
845
|
- Fixed `ask` timeout handling to auto-select the recommended option instead of aborting the turn, while preserving explicit user-cancel abort behavior ([#266](https://github.com/can1357/oh-my-pi/issues/266))
|
|
809
846
|
|
|
810
847
|
## [13.6.2] - 2026-03-03
|
|
848
|
+
|
|
811
849
|
### Fixed
|
|
812
850
|
|
|
813
851
|
- Fixed LM Studio API key retrieval to use configured provider name instead of hardcoded 'lm-studio'
|
|
@@ -822,7 +860,9 @@
|
|
|
822
860
|
- Fixed `omp update` silently succeeding without actually updating the binary when the update channel (bun global vs compiled binary) doesn't match the installation method ([#247](https://github.com/can1357/oh-my-pi/issues/247))
|
|
823
861
|
- Added post-update verification that checks the resolved `omp` binary reports the expected version, with actionable warnings on mismatch
|
|
824
862
|
- `omp update` now detects when the `omp` in PATH is not managed by bun and falls back to binary replacement instead of updating the wrong location
|
|
863
|
+
|
|
825
864
|
## [13.6.0] - 2026-03-03
|
|
865
|
+
|
|
826
866
|
### Added
|
|
827
867
|
|
|
828
868
|
- Added `mcp://` internal URL protocol for reading MCP server resources directly via the read tool (e.g., `read(path="mcp://resource-uri")`)
|
|
@@ -853,9 +893,11 @@
|
|
|
853
893
|
- Fixed URI template matching to correctly handle expressions that expand to empty strings
|
|
854
894
|
|
|
855
895
|
## [13.5.6] - 2026-03-01
|
|
896
|
+
|
|
856
897
|
### Changed
|
|
857
898
|
|
|
858
899
|
- Updated OAuth client name from 'oh-my-pi MCP' to 'Codex' for dynamic client registration
|
|
900
|
+
|
|
859
901
|
### Fixed
|
|
860
902
|
|
|
861
903
|
- Fixed exit_plan_mode handler to abort active agent turn before opening plan approval selector, ensuring proper session cleanup
|
|
@@ -867,6 +909,7 @@
|
|
|
867
909
|
- Added Kagi web search provider (Search API v0) with related searches support and automatic `KAGI_API_KEY` detection
|
|
868
910
|
|
|
869
911
|
## [13.5.4] - 2026-03-01
|
|
912
|
+
|
|
870
913
|
### Added
|
|
871
914
|
|
|
872
915
|
- Added `authServerUrl` field to `AuthDetectionResult` to capture OAuth server metadata from `Mcp-Auth-Server` headers
|
|
@@ -875,6 +918,7 @@
|
|
|
875
918
|
- Added recursive auth server discovery to follow `authorization_servers` references when discovering OAuth endpoints
|
|
876
919
|
|
|
877
920
|
- Added `omp agents unpack` CLI subcommand to export bundled subagent definitions to `~/.omp/agent/agents` by default, with `--project` support for `./.omp/agents`
|
|
921
|
+
|
|
878
922
|
### Changed
|
|
879
923
|
|
|
880
924
|
- Enhanced `discoverOAuthEndpoints()` to accept optional `authServerUrl` parameter and query both auth server and resource server for OAuth metadata
|
|
@@ -1569,7 +1613,7 @@
|
|
|
1569
1613
|
- Updated hashline reference format from `LINE:HASH` to `LINE#ID` throughout the codebase for improved clarity
|
|
1570
1614
|
- Renamed hashline edit operations: `set_line` → `set`, `replace_lines` → `set_range`, `insert_after` → `insert` with support for `before` and `between` anchors
|
|
1571
1615
|
- Changed hashline edit `body` field from string to array of strings for clearer multiline handling
|
|
1572
|
-
- Updated handlebars helpers: renamed `hashline` to `
|
|
1616
|
+
- Updated handlebars helpers: renamed `hashline` to `href` and added `hline` for formatted line output
|
|
1573
1617
|
- Improved insert operation to support `before`, `after`, and `between` (both anchors) positioning modes
|
|
1574
1618
|
- Made autocorrect heuristics (boundary echo stripping, indent restoration) conditional on `PI_HL_AUTOCORRECT` environment variable
|
|
1575
1619
|
- Updated SSH host discovery to load from managed omp config paths (.omp/ssh.json and ~/.omp/agent/ssh.json) in addition to legacy root-level ssh.json and .ssh.json files
|
|
@@ -1901,7 +1945,6 @@
|
|
|
1901
1945
|
- Improved error reporting in fetch tool to include HTTP status codes when URL fetching fails
|
|
1902
1946
|
- Fixed fetch tool to preserve actual response metadata (finalUrl, contentType) instead of defaults when requests fail
|
|
1903
1947
|
|
|
1904
|
-
|
|
1905
1948
|
## [12.1.0] - 2026-02-13
|
|
1906
1949
|
|
|
1907
1950
|
### Added
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-coding-agent",
|
|
4
|
-
"version": "13.16.
|
|
4
|
+
"version": "13.16.4",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://github.com/can1357/oh-my-pi",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -42,12 +42,12 @@
|
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@agentclientprotocol/sdk": "0.16.1",
|
|
44
44
|
"@mozilla/readability": "^0.6",
|
|
45
|
-
"@oh-my-pi/omp-stats": "13.16.
|
|
46
|
-
"@oh-my-pi/pi-agent-core": "13.16.
|
|
47
|
-
"@oh-my-pi/pi-ai": "13.16.
|
|
48
|
-
"@oh-my-pi/pi-natives": "13.16.
|
|
49
|
-
"@oh-my-pi/pi-tui": "13.16.
|
|
50
|
-
"@oh-my-pi/pi-utils": "13.16.
|
|
45
|
+
"@oh-my-pi/omp-stats": "13.16.4",
|
|
46
|
+
"@oh-my-pi/pi-agent-core": "13.16.4",
|
|
47
|
+
"@oh-my-pi/pi-ai": "13.16.4",
|
|
48
|
+
"@oh-my-pi/pi-natives": "13.16.4",
|
|
49
|
+
"@oh-my-pi/pi-tui": "13.16.4",
|
|
50
|
+
"@oh-my-pi/pi-utils": "13.16.4",
|
|
51
51
|
"@sinclair/typebox": "^0.34",
|
|
52
52
|
"@xterm/headless": "^6.0",
|
|
53
53
|
"ajv": "^8.18",
|
|
@@ -258,19 +258,19 @@ function formatHashlineRef(lineNum: unknown, content: unknown): { num: number; t
|
|
|
258
258
|
}
|
|
259
259
|
|
|
260
260
|
/**
|
|
261
|
-
* {{
|
|
261
|
+
* {{href lineNum "content"}} — compute a real hashline ref for prompt examples.
|
|
262
262
|
* Returns `"lineNum#hash"` using the actual hash algorithm.
|
|
263
263
|
*/
|
|
264
|
-
handlebars.registerHelper("
|
|
264
|
+
handlebars.registerHelper("href", (lineNum: unknown, content: unknown): string => {
|
|
265
265
|
const { ref } = formatHashlineRef(lineNum, content);
|
|
266
266
|
return JSON.stringify(ref);
|
|
267
267
|
});
|
|
268
268
|
|
|
269
269
|
/**
|
|
270
|
-
* {{
|
|
270
|
+
* {{hline lineNum "content"}} — format a full read-style line with prefix.
|
|
271
271
|
* Returns `"lineNum#hash:content"`.
|
|
272
272
|
*/
|
|
273
|
-
handlebars.registerHelper("
|
|
273
|
+
handlebars.registerHelper("hline", (lineNum: unknown, content: unknown): string => {
|
|
274
274
|
const { ref, text } = formatHashlineRef(lineNum, content);
|
|
275
275
|
return `${ref}:${text}`;
|
|
276
276
|
});
|
package/src/patch/index.ts
CHANGED
|
@@ -187,12 +187,9 @@ const locSchema = Type.Union(
|
|
|
187
187
|
Type.Object({ append: Type.String({ description: "anchor" }) }),
|
|
188
188
|
Type.Object({ prepend: Type.String({ description: "anchor" }) }),
|
|
189
189
|
Type.Object({
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
block: Type.Object({
|
|
194
|
-
pos: Type.String({ description: "anchor" }),
|
|
195
|
-
end: Type.String({ description: "limit position" }),
|
|
190
|
+
range: Type.Object({
|
|
191
|
+
pos: Type.String({ description: "first line to edit (inclusive)" }),
|
|
192
|
+
end: Type.String({ description: "last line to edit (inclusive)" }),
|
|
196
193
|
}),
|
|
197
194
|
}),
|
|
198
195
|
],
|
|
@@ -231,8 +228,7 @@ export type HashlineParams = Static<typeof hashlineEditParamsSchema>;
|
|
|
231
228
|
* loc can be:
|
|
232
229
|
* - "append" / "prepend" — file-level insert
|
|
233
230
|
* - { append: anchor } / { prepend: anchor } — insert relative to anchor
|
|
234
|
-
* - {
|
|
235
|
-
* - { replace_block: { pos, end } } — replace inclusive range
|
|
231
|
+
* - { range: { pos, end } } — replace inclusive range
|
|
236
232
|
*/
|
|
237
233
|
function resolveEditAnchors(edits: HashlineToolEdit[]): HashlineEdit[] {
|
|
238
234
|
const result: HashlineEdit[] = [];
|
|
@@ -253,17 +249,13 @@ function resolveEditAnchors(edits: HashlineToolEdit[]): HashlineEdit[] {
|
|
|
253
249
|
const anchor = tryParseTag(loc.prepend);
|
|
254
250
|
if (!anchor) throw new Error("prepend requires a valid anchor.");
|
|
255
251
|
result.push({ op: "prepend_at", pos: anchor, lines });
|
|
256
|
-
} else if ("
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
} else if ("block" in loc) {
|
|
261
|
-
const posAnchor = tryParseTag(loc.block.pos);
|
|
262
|
-
const endAnchor = tryParseTag(loc.block.end);
|
|
263
|
-
if (!posAnchor || !endAnchor) throw new Error("block requires valid pos and end anchors.");
|
|
252
|
+
} else if ("range" in loc) {
|
|
253
|
+
const posAnchor = tryParseTag(loc.range.pos);
|
|
254
|
+
const endAnchor = tryParseTag(loc.range.end);
|
|
255
|
+
if (!posAnchor || !endAnchor) throw new Error("range requires valid pos and end anchors.");
|
|
264
256
|
result.push({ op: "replace_range", pos: posAnchor, end: endAnchor, lines });
|
|
265
257
|
} else {
|
|
266
|
-
throw new Error("Unknown loc shape. Expected append, prepend,
|
|
258
|
+
throw new Error("Unknown loc shape. Expected append, prepend, or range.");
|
|
267
259
|
}
|
|
268
260
|
} else {
|
|
269
261
|
throw new Error(`Invalid loc value: ${JSON.stringify(loc)}`);
|
package/src/patch/shared.ts
CHANGED
|
@@ -164,9 +164,8 @@ function formatStreamingHashlineEdits(edits: Partial<HashlineToolEdit>[], uiThem
|
|
|
164
164
|
return { srcLabel: `• ${loc} (file-level)`, dst: contentLines };
|
|
165
165
|
}
|
|
166
166
|
if (typeof loc === "object" && loc) {
|
|
167
|
-
if ("
|
|
168
|
-
|
|
169
|
-
return { srcLabel: `• block ${rb.pos ?? "?"}…${rb.end ?? "?"}`, dst: contentLines };
|
|
167
|
+
if ("range" in loc && typeof loc.range === "object" && loc.range) {
|
|
168
|
+
return { srcLabel: `• range ${loc.range.pos ?? "?"}…${loc.range.end ?? "?"}`, dst: contentLines };
|
|
170
169
|
}
|
|
171
170
|
if ("line" in loc) {
|
|
172
171
|
return { srcLabel: `• line ${(loc as { line: string }).line}`, dst: contentLines };
|
|
@@ -16,40 +16,39 @@ Read the file first. Copy anchors exactly from the latest `read` output. In one
|
|
|
16
16
|
**`loc` values**
|
|
17
17
|
- `"append"` / `"prepend"` — insert at end/start of file
|
|
18
18
|
- `{ append: "N#ID" }` / `{ prepend: "N#ID" }` — insert after/before anchored line
|
|
19
|
-
- `{
|
|
20
|
-
|
|
21
|
-
</operations>
|
|
19
|
+
- `{ range: { pos: "N#ID", end: "N#ID" } }` — replace inclusive range of lines `pos..end` with new content
|
|
20
|
+
</operations>
|
|
22
21
|
|
|
23
22
|
<examples>
|
|
24
|
-
All examples below reference the same file
|
|
25
|
-
```ts
|
|
26
|
-
{{
|
|
27
|
-
{{
|
|
28
|
-
{{
|
|
29
|
-
{{
|
|
30
|
-
{{
|
|
31
|
-
{{
|
|
32
|
-
{{
|
|
33
|
-
{{
|
|
34
|
-
{{
|
|
35
|
-
{{
|
|
36
|
-
{{
|
|
37
|
-
{{
|
|
38
|
-
{{
|
|
39
|
-
{{
|
|
40
|
-
{{
|
|
41
|
-
{{
|
|
42
|
-
{{
|
|
43
|
-
{{
|
|
23
|
+
All examples below reference the same file:
|
|
24
|
+
```ts title="a.ts"
|
|
25
|
+
{{hline 1 "// @ts-ignore"}}
|
|
26
|
+
{{hline 2 "const timeout = 5000;"}}
|
|
27
|
+
{{hline 3 "const tag = \"DO NOT SHIP\";"}}
|
|
28
|
+
{{hline 4 ""}}
|
|
29
|
+
{{hline 5 "function alpha() {"}}
|
|
30
|
+
{{hline 6 "\tlog();"}}
|
|
31
|
+
{{hline 7 "}"}}
|
|
32
|
+
{{hline 8 ""}}
|
|
33
|
+
{{hline 9 "function beta() {"}}
|
|
34
|
+
{{hline 10 "\t// TODO: remove after migration"}}
|
|
35
|
+
{{hline 11 "\tlegacy();"}}
|
|
36
|
+
{{hline 12 "\ttry {"}}
|
|
37
|
+
{{hline 13 "\t\treturn parse(data);"}}
|
|
38
|
+
{{hline 14 "\t} catch (err) {"}}
|
|
39
|
+
{{hline 15 "\t\tconsole.error(err);"}}
|
|
40
|
+
{{hline 16 "\t\treturn null;"}}
|
|
41
|
+
{{hline 17 "\t}"}}
|
|
42
|
+
{{hline 18 "}"}}
|
|
44
43
|
```
|
|
45
44
|
|
|
46
45
|
<example name="replace a block body">
|
|
47
46
|
Replace only the catch body. Do not target the shared boundary line `} catch (err) {`.
|
|
48
47
|
```
|
|
49
48
|
{
|
|
50
|
-
path: "
|
|
49
|
+
path: "a.ts",
|
|
51
50
|
edits: [{
|
|
52
|
-
loc: {
|
|
51
|
+
loc: { range: { pos: {{href 15 "\t\tconsole.error(err);"}}, end: {{href 16 "\t\treturn null;"}} } },
|
|
53
52
|
content: [
|
|
54
53
|
"\t\tif (isEnoent(err)) return null;",
|
|
55
54
|
"\t\tthrow err;"
|
|
@@ -60,12 +59,12 @@ Replace only the catch body. Do not target the shared boundary line `} catch (er
|
|
|
60
59
|
</example>
|
|
61
60
|
|
|
62
61
|
<example name="replace whole block including closing brace">
|
|
63
|
-
Replace the entire body of `alpha`, including its closing `}`. `end` **MUST** be {{
|
|
62
|
+
Replace the entire body of `alpha`, including its closing `}`. `end` **MUST** be {{href 7 "}"}} because `content` includes `}`.
|
|
64
63
|
```
|
|
65
64
|
{
|
|
66
|
-
path: "
|
|
65
|
+
path: "a.ts",
|
|
67
66
|
edits: [{
|
|
68
|
-
loc: {
|
|
67
|
+
loc: { range: { pos: {{href 6 "\tlog();"}}, end: {{href 7 "}"}} } },
|
|
69
68
|
content: [
|
|
70
69
|
"\tvalidate();",
|
|
71
70
|
"\tlog();",
|
|
@@ -74,15 +73,15 @@ Replace the entire body of `alpha`, including its closing `}`. `end` **MUST** be
|
|
|
74
73
|
}]
|
|
75
74
|
}
|
|
76
75
|
```
|
|
77
|
-
**Wrong**: using `end: {{
|
|
76
|
+
**Wrong**: using `end: {{href 6 "\tlog();"}}` with the same content — line 7 (`}`) survives the replacement AND content emits `}`, producing two closing braces.
|
|
78
77
|
</example>
|
|
79
78
|
|
|
80
79
|
<example name="replace one line">
|
|
81
80
|
```
|
|
82
81
|
{
|
|
83
|
-
path: "
|
|
82
|
+
path: "a.ts",
|
|
84
83
|
edits: [{
|
|
85
|
-
loc: {
|
|
84
|
+
loc: { range: { pos: {{href 2 "const timeout = 5000;"}}, end: {{href 2 "const timeout = 5000;"}} } },
|
|
86
85
|
content: ["const timeout = 30_000;"]
|
|
87
86
|
}]
|
|
88
87
|
}
|
|
@@ -92,9 +91,9 @@ Replace the entire body of `alpha`, including its closing `}`. `end` **MUST** be
|
|
|
92
91
|
<example name="delete a range">
|
|
93
92
|
```
|
|
94
93
|
{
|
|
95
|
-
path: "
|
|
94
|
+
path: "a.ts",
|
|
96
95
|
edits: [{
|
|
97
|
-
loc: {
|
|
96
|
+
loc: { range: { pos: {{href 10 "\t// TODO: remove after migration"}}, end: {{href 11 "\tlegacy();"}} } },
|
|
98
97
|
content: null
|
|
99
98
|
}]
|
|
100
99
|
}
|
|
@@ -105,9 +104,9 @@ Replace the entire body of `alpha`, including its closing `}`. `end` **MUST** be
|
|
|
105
104
|
When adding a sibling declaration, prefer `prepend` on the next declaration.
|
|
106
105
|
```
|
|
107
106
|
{
|
|
108
|
-
path: "
|
|
107
|
+
path: "a.ts",
|
|
109
108
|
edits: [{
|
|
110
|
-
loc: { prepend: {{
|
|
109
|
+
loc: { prepend: {{href 9 "function beta() {"}} },
|
|
111
110
|
content: [
|
|
112
111
|
"function gamma() {",
|
|
113
112
|
"\tvalidate();",
|
|
@@ -123,10 +122,10 @@ When adding a sibling declaration, prefer `prepend` on the next declaration.
|
|
|
123
122
|
<critical>
|
|
124
123
|
- Make the minimum exact edit. Do not rewrite nearby code unless the consumed range requires it.
|
|
125
124
|
- Use anchors exactly as `N#ID` from the latest `read` output.
|
|
126
|
-
- `
|
|
125
|
+
- `range` requires both `pos` and `end`.
|
|
127
126
|
- When your replacement `content` ends with a closing delimiter (`}`, `*/`, `)`, `]`), verify `end` includes the original line carrying that delimiter. If `end` stops one line too early, the original delimiter survives and your content adds a second copy.
|
|
128
127
|
- **Self-check**: compare the last line of `content` with the line immediately after `end` in the file. If they match (e.g., both are `}`), extend `end` to include that line.
|
|
129
|
-
- For a
|
|
128
|
+
- For a range, either replace only the body or replace the whole range. Do not split range boundaries.
|
|
130
129
|
- `content` must be literal file content with matching indentation. If the file uses tabs, use real tabs.
|
|
131
|
-
-
|
|
132
|
-
</critical>
|
|
130
|
+
- You **MUST NOT** use this tool to reformat or clean up unrelated code. **ALWAYS** use project-specific tooling like linters or code formatters which are much more efficient and reliable.
|
|
131
|
+
</critical>
|
|
@@ -16,7 +16,7 @@ const CHECK_BYTE_COUNT = 1024;
|
|
|
16
16
|
const HEADER_LINE_LIMIT = 40;
|
|
17
17
|
|
|
18
18
|
const KNOWN_GENERATOR_PATTERN =
|
|
19
|
-
"(?:protoc(?:-gen-[\\w-]+)?|sqlc|buf|swagger(?:-codegen)?|openapi(?:-generator)?|grpc-gateway|mockery|stringer|easyjson|deepcopy-gen|defaulter-gen|conversion-gen|client-gen|lister-gen|informer-gen)";
|
|
19
|
+
"(?:protoc(?:-gen-[\\w-]+)?|sqlc|buf|swagger(?:-codegen)?|openapi(?:-generator)?|grpc-gateway|mockery|stringer|easyjson|deepcopy-gen|defaulter-gen|conversion-gen|client-gen|lister-gen|informer-gen|kysely-codegen)";
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* Strong marker patterns for generated-file headers.
|