@oh-my-pi/hashline 17.2.15 → 17.3.0
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 +6 -0
- package/dist/types/apply.d.ts +13 -15
- package/dist/types/messages.d.ts +20 -33
- package/dist/types/syntax.d.ts +8 -7
- package/package.json +3 -3
- package/src/apply.ts +536 -1003
- package/src/messages.ts +39 -58
- package/src/prompt.md +4 -2
- package/src/syntax.ts +33 -7
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [17.3.0] - 2026-08-13
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Repaired mis-set replacement ranges using exact outside-row matches, indentation, tree-sitter structure, and a narrow pure-closer shape: opening comment fences and other syntax-essential edges are retained only when a parse-valid candidate satisfies those constraints; ambiguous placements are rejected.
|
|
10
|
+
|
|
5
11
|
## [17.2.15] - 2026-08-12
|
|
6
12
|
|
|
7
13
|
### Added
|
package/dist/types/apply.d.ts
CHANGED
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
* post-edit lines plus any diagnostic warnings. Pure function: no FS, no
|
|
4
4
|
* mutation of the input.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* Mis-set replacement range boundaries are repaired by bounded candidate
|
|
7
|
+
* search. Exact line equality, indentation, tree-sitter structure, and a
|
|
8
|
+
* narrow pure-closer shape gate constrain candidates; tree-sitter validates
|
|
9
|
+
* the selected result.
|
|
9
10
|
*/
|
|
10
11
|
import type { ApplyResult, Clipboard, Edit } from "./types.js";
|
|
11
12
|
/** A line that is nothing but closing delimiters: `}`, `)`, `];`, `})`, `},`. */
|
|
@@ -21,11 +22,10 @@ export interface ApplyEditsOptions {
|
|
|
21
22
|
/** Anonymous `PASTE` with an empty register: `throw` (default) or `drop` (streaming previews). An empty named-register paste never throws — it warns and pastes nothing. */
|
|
22
23
|
onEmptyPaste?: "throw" | "drop";
|
|
23
24
|
/**
|
|
24
|
-
* Target
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* no veto and the delimiter heuristics decide alone.
|
|
25
|
+
* Target path used to infer a language for the tree-sitter syntax probe.
|
|
26
|
+
* Required for syntax-essential boundary retention and post-apply syntax
|
|
27
|
+
* advisories. Without it, only exact-text boundary normalization and its
|
|
28
|
+
* evidence-complete rejections run.
|
|
29
29
|
*/
|
|
30
30
|
path?: string;
|
|
31
31
|
}
|
|
@@ -35,12 +35,10 @@ export interface ApplyEditsOptions {
|
|
|
35
35
|
* Returns the post-edit text and the first changed line number (1-indexed).
|
|
36
36
|
* Throws if an anchor is out of bounds.
|
|
37
37
|
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* authored result does not parse — or the language is unknown to the parser, so
|
|
44
|
-
* balance arithmetic is the sole evidence — do the closer-spare repairs run.
|
|
38
|
+
* Mis-set replacement boundaries are repaired by {@link repairBoundaryVariants}
|
|
39
|
+
* when `options.path` lets tree-sitter judge the result. A parsing authored
|
|
40
|
+
* result is never second-guessed. For a broken result, only syntax-essential
|
|
41
|
+
* edge retention with matching indentation and exact outside-row echo removal
|
|
42
|
+
* are considered; every selected candidate must parse.
|
|
45
43
|
*/
|
|
46
44
|
export declare function applyEdits(text: string, edits: readonly Edit[], options?: ApplyEditsOptions): ApplyResult;
|
package/dist/types/messages.d.ts
CHANGED
|
@@ -86,50 +86,35 @@ export declare function pasteAfterBlockCloserLoweredWarning(line: number): strin
|
|
|
86
86
|
/** Register `PUT >N*` anchor unresolvable; applied as `PUT >N`. */
|
|
87
87
|
export declare function pasteAfterBlockUnresolvedLoweredWarning(line: number): string;
|
|
88
88
|
/**
|
|
89
|
-
* A one-sided boundary echo
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
* edit is rejected instead of repaired.
|
|
89
|
+
* A one-sided exact boundary echo cannot cover the selected range after the
|
|
90
|
+
* duplicated body rows are removed. Applying or dropping it would lose
|
|
91
|
+
* distinct range content, so the edit is rejected unless a parse-restoring
|
|
92
|
+
* boundary combination proves another reading.
|
|
94
93
|
*/
|
|
95
94
|
export declare function ambiguousBoundaryEchoMessage(startLine: number, endLine: number, side: "leading" | "trailing", count: number): string;
|
|
96
95
|
/**
|
|
97
|
-
* A
|
|
98
|
-
*
|
|
99
|
-
* terminate: the payload has no unmatched opener for them and its indentation
|
|
100
|
-
* is not deeper than the closer. Sparing the closer would have to guess
|
|
101
|
-
* whether the payload belongs before it (inside the block) or after it (a
|
|
102
|
-
* sibling), so the edit is rejected instead of repaired.
|
|
96
|
+
* A syntax-essential selected edge can be retained on either side of the
|
|
97
|
+
* payload, but indentation does not establish which placement was intended.
|
|
103
98
|
*/
|
|
104
|
-
export declare function
|
|
99
|
+
export declare function ambiguousBoundaryPlacementMessage(startLine: number, endLine: number): string;
|
|
105
100
|
/**
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
* the construct above" mistake — but the payload's indentation claims a depth
|
|
109
|
-
* inside the block those closers terminate, so whether the new content
|
|
110
|
-
* belongs before or after the spared closer is ambiguous. Rejected instead of
|
|
111
|
-
* repaired; the at-or-above-depth reading is auto-repaired by sparing the
|
|
112
|
-
* closer ahead of the payload.
|
|
101
|
+
* Exact-text boundary rows were removed because the remaining payload covers
|
|
102
|
+
* the selected range and the same rows already survive immediately outside it.
|
|
113
103
|
*/
|
|
114
|
-
export declare function
|
|
104
|
+
export declare function textualBoundaryEchoWarning(startLine: number, leading: number, trailing: number): string;
|
|
115
105
|
/**
|
|
116
|
-
* A replacement range
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
* and opener/closer text shape cannot prove a syntactic block (the braces may
|
|
121
|
-
* be literal prose), so the edit applies as authored and the author decides.
|
|
106
|
+
* A replacement range's boundary disposition was corrected by the
|
|
107
|
+
* syntax-probe-judged search: syntax-essential source boundary rows were
|
|
108
|
+
* retained, or exact body echoes of surviving outside rows were removed. The
|
|
109
|
+
* authored result did not parse and the selected result does.
|
|
122
110
|
*/
|
|
123
|
-
export declare function
|
|
111
|
+
export declare function boundaryVariantRepairWarning(startLine: number, kept: number, dropped: number): string;
|
|
124
112
|
/**
|
|
125
113
|
* The applied result no longer parses while the pre-edit content did: the
|
|
126
114
|
* patch introduced a syntax error. Advisory, never a rejection — the applier
|
|
127
|
-
* honors the authored edit — but the breakage is machine-confirmed
|
|
128
|
-
* tree-sitter
|
|
129
|
-
*
|
|
130
|
-
* classic trigger is a balance-neutral misplacement: a statement landed on
|
|
131
|
-
* the wrong line number with no delimiter anomaly for the repair heuristics
|
|
132
|
-
* to notice.
|
|
115
|
+
* honors the authored edit — but the breakage is machine-confirmed by
|
|
116
|
+
* tree-sitter and surfaced in the same response instead of waiting for a
|
|
117
|
+
* compiler pass.
|
|
133
118
|
*/
|
|
134
119
|
export declare function editBrokeParseWarning(firstChangedLine: number | undefined): string;
|
|
135
120
|
/**
|
|
@@ -137,6 +122,8 @@ export declare function editBrokeParseWarning(firstChangedLine: number | undefin
|
|
|
137
122
|
* `resolveBlockEdits` must run first.
|
|
138
123
|
*/
|
|
139
124
|
export declare const UNRESOLVED_BLOCK_INTERNAL = "internal error: unresolved block edit reached the applier (resolveBlockEdits was not run).";
|
|
125
|
+
/** Internal invariant: clipboard edits must be concrete before application. */
|
|
126
|
+
export declare const UNRESOLVED_CLIPBOARD_INTERNAL = "internal error: unresolved clipboard edit reached the applier (resolveClipboardEdits was not run).";
|
|
140
127
|
/** `REM` received a body row or coexists with line edits. */
|
|
141
128
|
export declare const REM_TAKES_NO_BODY = "`REM` deletes the whole file and takes no body rows or line ops. Issue it alone under the header.";
|
|
142
129
|
/** `MV` received a body row. */
|
package/dist/types/syntax.d.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Syntax probe for candidate edit results, via the native tree-sitter parser.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* heuristics as the only available evidence.
|
|
4
|
+
* Replacement-boundary repair uses parsing as its semantic filter: exact
|
|
5
|
+
* outside-row equality may justify dropping a duplicated payload edge, while
|
|
6
|
+
* retaining a selected source boundary additionally requires source-range
|
|
7
|
+
* structure, indentation, or a narrow pure-closer shape. An unrecognized
|
|
8
|
+
* language yields no structural proof, so only evidence-complete textual
|
|
9
|
+
* normalization remains available.
|
|
11
10
|
*/
|
|
11
|
+
/** Syntactic node boundaries outside a visible source range. */
|
|
12
|
+
export declare function enclosingBoundaries(lines: readonly string[], path: string, startLine: number, endLine: number): readonly number[];
|
|
12
13
|
/**
|
|
13
14
|
* `true` when `text` parses without a syntax error under the language inferred
|
|
14
15
|
* from `path`. `false` covers "does not parse" and "cannot tell" alike — no
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/hashline",
|
|
4
|
-
"version": "17.
|
|
4
|
+
"version": "17.3.0",
|
|
5
5
|
"description": "Hashline: a compact, line-anchored patch language and applier. Pluggable FS/IO so it works over disk, in-memory, or any custom backend.",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"fmt": "biome format --write ."
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@oh-my-pi/pi-natives": "17.
|
|
37
|
-
"@oh-my-pi/pi-utils": "17.
|
|
36
|
+
"@oh-my-pi/pi-natives": "17.3.0",
|
|
37
|
+
"@oh-my-pi/pi-utils": "17.3.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/bun": "^1.3.14"
|