@oh-my-pi/hashline 16.1.1 → 16.1.2
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/package.json +1 -1
- package/src/prompt.md +13 -16
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/hashline",
|
|
4
|
-
"version": "16.1.
|
|
4
|
+
"version": "16.1.2",
|
|
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",
|
package/src/prompt.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Your patch language names lines to replace, delete, or insert at, then lists the new content. Rule of thumb: a header ending in `:` is followed by `+` body rows; `DEL` has no body.
|
|
2
2
|
|
|
3
3
|
<headers>
|
|
4
|
-
Every file section starts with `[PATH#TAG]`. `TAG`
|
|
4
|
+
Every file section starts with `[PATH#TAG]`. `TAG` = 4-hex snapshot tag from your latest `read`/`search`, REQUIRED on every section — no hashless form. Create new files with `write`; hashline only edits existing files.
|
|
5
5
|
</headers>
|
|
6
6
|
|
|
7
7
|
<ops>
|
|
@@ -12,33 +12,30 @@ Every file section starts with `[PATH#TAG]`. `TAG` is the 4-hex snapshot tag fro
|
|
|
12
12
|
`INS.PRE N:` — insert the body rows immediately before line N.
|
|
13
13
|
`INS.POST N:` — insert the body rows immediately after line N.
|
|
14
14
|
`INS.BLK.POST N:` — insert the body rows after the END of the block that BEGINS on line N — outside it, at sibling depth. To append inside a block, use `INS.POST`.
|
|
15
|
-
`INS.HEAD:` — insert the body rows at the very start of the file.
|
|
16
|
-
`INS.TAIL:` — insert the body rows at the very end of the file.
|
|
15
|
+
`INS.HEAD:` / `INS.TAIL:` — insert the body rows at the very start / end of the file.
|
|
17
16
|
Single line: `SWAP N.=N:` / `DEL N`. The range is the ORIGINAL lines you touch; body length is irrelevant (replacing 1 line with 10 is still `SWAP N.=N:`).
|
|
18
17
|
</ops>
|
|
19
18
|
|
|
20
19
|
<body-rows>
|
|
21
|
-
Body rows appear only under a `:` header. Every body row is:
|
|
22
|
-
+TEXT add a new literal line `TEXT`, verbatim (leading whitespace kept). `+` alone adds a blank line.
|
|
23
|
-
There is NO other body row kind. NEVER write `-old` or a bare/context line. To keep a line, leave it out of every range. To insert a literal line starting with `-` or `+`, prefix it: `+-x`, `++x`.
|
|
20
|
+
Body rows appear only under a `:` header. Every body row is `+TEXT` — add a literal line `TEXT`, verbatim (leading whitespace kept); `+` alone adds a blank line. No other row kind. NEVER write `-old` or a bare/context line. To keep a line, leave it out of every range. To insert a literal line starting with `-` or `+`, prefix it: `+-x`, `++x`.
|
|
24
21
|
</body-rows>
|
|
25
22
|
|
|
26
23
|
<rules>
|
|
27
|
-
- Line numbers
|
|
28
|
-
- Numbers refer to the ORIGINAL file;
|
|
24
|
+
- Line numbers + `[PATH#TAG]` header come from your latest `read`/`search` (`LINE:TEXT` rows).
|
|
25
|
+
- Numbers refer to the ORIGINAL file; never shift as hunks apply.
|
|
29
26
|
- They die with the call: every applied edit mints a fresh `#TAG` and renumbers — anchor the next edit on the edit response or a fresh `read`.
|
|
30
|
-
- Touch only lines your latest `read`/`search` literally displayed as `LINE:TEXT`; the tag certifies the snapshot, not your memory
|
|
31
|
-
- Elided regions are UNSEEN: `…`/`..` markers and a collapsed `N-M:` summary row (only boundary lines N and M
|
|
27
|
+
- Touch only lines your latest `read`/`search` literally displayed as `LINE:TEXT`; the tag certifies the snapshot, not your memory. A hunk anchored on a line you never displayed is REJECTED — re-`read` first. Seeing a line ≠ it holds the code you mean; confirm numbers map to the construct you intend, especially far from your read window.
|
|
28
|
+
- Elided regions are UNSEEN: `…`/`..` markers and a collapsed `N-M:` summary row (only boundary lines N and M shown) hide their interior. NEVER place or span a hunk inside one — `read` the range first.
|
|
32
29
|
- Never start or end a range mid-expression or mid-block.
|
|
33
30
|
- Indent body rows exactly for the depth they should live at.
|
|
34
31
|
- On a stale-tag rejection or any surprising result: STOP and re-`read` before further edits.
|
|
35
|
-
- One hunk per range;
|
|
32
|
+
- One hunk per range; body = final content, never an old/new pair.
|
|
36
33
|
- Ranges cover ONLY lines whose content changes. Never widen over unchanged lines — a stale wide range shreds everything it spans.
|
|
37
34
|
- Whole construct → `SWAP.BLK N` (tree-sitter resolves the end); lines inside it → `SWAP N.=M`.
|
|
38
35
|
- `SWAP.BLK N` resolves EXACTLY the node at N. Leading decorators/attributes/doc-comments are separate nodes: point N at the FIRST decorator to sweep both; standalone line-comments are never swept — use `SWAP N.=M`.
|
|
39
|
-
- Block ops (`SWAP.BLK`/`DEL.BLK`/`INS.BLK.POST`) anchor the OPENING line of a MULTI-LINE construct — never its closer,
|
|
36
|
+
- Block ops (`SWAP.BLK`/`DEL.BLK`/`INS.BLK.POST`) anchor the OPENING line of a MULTI-LINE construct — never its closer, last line, or a bare inner statement. Anchoring one statement resolves to ONE line and is REJECTED: use the plain op (`SWAP N.=N` / `DEL N` / `INS.POST N`), or point N at the real opener. Saw the closer? Use plain `INS.POST M:`.
|
|
40
37
|
- Non-adjacent changes = separate hunks; untouched lines stay out of every range.
|
|
41
|
-
- Pure additions use `INS.PRE` / `INS.POST` / `INS.HEAD` / `INS.TAIL`, never a widened `SWAP` — retyped keepers are exactly what gets dropped. A multi-line `SWAP` whose body restates the line just
|
|
38
|
+
- Pure additions use `INS.PRE` / `INS.POST` / `INS.HEAD` / `INS.TAIL`, never a widened `SWAP` — retyped keepers are exactly what gets dropped. (A multi-line `SWAP` whose body restates the line just past the range is auto-dropped as an off-by-one keeper with a warning — issue the payload for the range only; never lean on the repair.)
|
|
42
39
|
- NEVER format/restyle code with this tool; run the project formatter instead.
|
|
43
40
|
</rules>
|
|
44
41
|
|
|
@@ -90,7 +87,7 @@ SWAP.BLK 1:
|
|
|
90
87
|
+ print(f"Hello, {name}")
|
|
91
88
|
```
|
|
92
89
|
|
|
93
|
-
A decorator
|
|
90
|
+
A decorator/doc-comment is a SEPARATE block — `SWAP.BLK` on the `def`/`fn` line keeps it. Point N at the decorator to take both; here line 1 is `@cache`, so anchoring on the `def` (line 2) would orphan `@cache`:
|
|
94
91
|
```
|
|
95
92
|
[svc.py#C3D4]
|
|
96
93
|
SWAP.BLK 1:
|
|
@@ -117,8 +114,8 @@ SWAP 3.=3:
|
|
|
117
114
|
SWAP 3.=3:
|
|
118
115
|
+ return msg
|
|
119
116
|
|
|
120
|
-
# WRONG — a pure insertion done as a widened `SWAP`: you
|
|
121
|
-
# but you replace 2.=4, retype the keepers
|
|
117
|
+
# WRONG — a pure insertion done as a widened `SWAP`: you want to add one line after 2,
|
|
118
|
+
# but you replace 2.=4, retype the keepers, and drop one (here line 4, `greet("world")`).
|
|
122
119
|
SWAP 2.=4:
|
|
123
120
|
+ msg = "Hello, " + name
|
|
124
121
|
+ extra = compute(name)
|