@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.*, task.eager, task.maxConcurrency, task.maxRecursionDepth) to the Tasks tab
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 `hlineref` Handlebars helper to return JSON-quoted strings for safer embedding in JSON blocks within prompts
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 `hlineref` and added `hlinefull` for formatted line output
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.3",
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.3",
46
- "@oh-my-pi/pi-agent-core": "13.16.3",
47
- "@oh-my-pi/pi-ai": "13.16.3",
48
- "@oh-my-pi/pi-natives": "13.16.3",
49
- "@oh-my-pi/pi-tui": "13.16.3",
50
- "@oh-my-pi/pi-utils": "13.16.3",
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
- * {{hlineref lineNum "content"}} — compute a real hashline ref for prompt examples.
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("hlineref", (lineNum: unknown, content: unknown): string => {
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
- * {{hlinefull lineNum "content"}} — format a full read-style line with prefix.
270
+ * {{hline lineNum "content"}} — format a full read-style line with prefix.
271
271
  * Returns `"lineNum#hash:content"`.
272
272
  */
273
- handlebars.registerHelper("hlinefull", (lineNum: unknown, content: unknown): string => {
273
+ handlebars.registerHelper("hline", (lineNum: unknown, content: unknown): string => {
274
274
  const { ref, text } = formatHashlineRef(lineNum, content);
275
275
  return `${ref}:${text}`;
276
276
  });
@@ -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
- line: Type.String({ description: "anchor" }),
191
- }),
192
- Type.Object({
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
- * - { replace_line: anchor } — replace one line
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 ("line" in loc) {
257
- const anchor = tryParseTag(loc.line);
258
- if (!anchor) throw new Error("line requires a valid anchor.");
259
- result.push({ op: "replace_line", pos: anchor, lines });
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, line, or block.");
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)}`);
@@ -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 ("block" in loc && typeof loc.block === "object" && loc.block) {
168
- const rb = loc.block as { pos?: string; end?: string };
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
- - `{ line: "N#ID" }` — replace exactly one anchored line
20
- - `{ block: { pos: "N#ID", end: "N#ID" } }` — replace inclusive `pos..end`
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, `util.ts`:
25
- ```ts
26
- {{hlinefull 1 "// @ts-ignore"}}
27
- {{hlinefull 2 "const timeout = 5000;"}}
28
- {{hlinefull 3 "const tag = \"DO NOT SHIP\";"}}
29
- {{hlinefull 4 ""}}
30
- {{hlinefull 5 "function alpha() {"}}
31
- {{hlinefull 6 "\tlog();"}}
32
- {{hlinefull 7 "}"}}
33
- {{hlinefull 8 ""}}
34
- {{hlinefull 9 "function beta() {"}}
35
- {{hlinefull 10 "\t// TODO: remove after migration"}}
36
- {{hlinefull 11 "\tlegacy();"}}
37
- {{hlinefull 12 "\ttry {"}}
38
- {{hlinefull 13 "\t\treturn parse(data);"}}
39
- {{hlinefull 14 "\t} catch (err) {"}}
40
- {{hlinefull 15 "\t\tconsole.error(err);"}}
41
- {{hlinefull 16 "\t\treturn null;"}}
42
- {{hlinefull 17 "\t}"}}
43
- {{hlinefull 18 "}"}}
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: "util.ts",
49
+ path: "a.ts",
51
50
  edits: [{
52
- loc: { block: { pos: {{hlineref 15 "\t\tconsole.error(err);"}}, end: {{hlineref 16 "\t\treturn null;"}} } },
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 {{hlineref 7 "}"}} because `content` includes `}`.
62
+ Replace the entire body of `alpha`, including its closing `}`. `end` **MUST** be {{href 7 "}"}} because `content` includes `}`.
64
63
  ```
65
64
  {
66
- path: "util.ts",
65
+ path: "a.ts",
67
66
  edits: [{
68
- loc: { block: { pos: {{hlineref 6 "\tlog();"}}, end: {{hlineref 7 "}"}} } },
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: {{hlineref 6 "\tlog();"}}` with the same content — line 7 (`}`) survives the replacement AND content emits `}`, producing two closing braces.
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: "util.ts",
82
+ path: "a.ts",
84
83
  edits: [{
85
- loc: { line: {{hlineref 2 "const timeout = 5000;"}} },
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: "util.ts",
94
+ path: "a.ts",
96
95
  edits: [{
97
- loc: { block: { pos: {{hlineref 10 "\t// TODO: remove after migration"}}, end: {{hlineref 11 "\tlegacy();"}} } },
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: "util.ts",
107
+ path: "a.ts",
109
108
  edits: [{
110
- loc: { prepend: {{hlineref 9 "function beta() {"}} },
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
- - `block` requires both `pos` and `end`. Other anchored ops require one anchor.
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 block, either replace only the body or replace the whole block. Do not split block boundaries.
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
- - Do not use this tool to reformat or clean up unrelated code.
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.