@oh-my-pi/hashline 15.5.9 → 15.5.11
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/dist/types/mismatch.d.ts +9 -0
- package/package.json +1 -1
- package/src/mismatch.ts +19 -1
- package/src/patcher.ts +1 -0
package/dist/types/mismatch.d.ts
CHANGED
|
@@ -10,6 +10,14 @@ export interface MismatchDetails {
|
|
|
10
10
|
actualFileHash: string;
|
|
11
11
|
fileLines: string[];
|
|
12
12
|
anchorLines?: readonly number[];
|
|
13
|
+
/**
|
|
14
|
+
* `true` when the section's expected hash resolved to a recorded snapshot
|
|
15
|
+
* (file content drifted since that snapshot), `false` when no snapshot
|
|
16
|
+
* was ever recorded for the hash (likely fabricated or carried over from
|
|
17
|
+
* a prior session). Drives a more actionable rejection message; defaults
|
|
18
|
+
* to `true` for backward compatibility with direct callers.
|
|
19
|
+
*/
|
|
20
|
+
hashRecognized?: boolean;
|
|
13
21
|
}
|
|
14
22
|
/**
|
|
15
23
|
* Raised when a hashline section's snapshot tag doesn't match the live file's
|
|
@@ -23,6 +31,7 @@ export declare class MismatchError extends Error {
|
|
|
23
31
|
readonly actualFileHash: string;
|
|
24
32
|
readonly fileLines: string[];
|
|
25
33
|
readonly anchorLines: readonly number[];
|
|
34
|
+
readonly hashRecognized: boolean;
|
|
26
35
|
constructor(details: MismatchDetails);
|
|
27
36
|
get displayMessage(): string;
|
|
28
37
|
static rejectionHeader(details: MismatchDetails): string[];
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/hashline",
|
|
4
|
-
"version": "15.5.
|
|
4
|
+
"version": "15.5.11",
|
|
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/mismatch.ts
CHANGED
|
@@ -37,6 +37,14 @@ export interface MismatchDetails {
|
|
|
37
37
|
actualFileHash: string;
|
|
38
38
|
fileLines: string[];
|
|
39
39
|
anchorLines?: readonly number[];
|
|
40
|
+
/**
|
|
41
|
+
* `true` when the section's expected hash resolved to a recorded snapshot
|
|
42
|
+
* (file content drifted since that snapshot), `false` when no snapshot
|
|
43
|
+
* was ever recorded for the hash (likely fabricated or carried over from
|
|
44
|
+
* a prior session). Drives a more actionable rejection message; defaults
|
|
45
|
+
* to `true` for backward compatibility with direct callers.
|
|
46
|
+
*/
|
|
47
|
+
hashRecognized?: boolean;
|
|
40
48
|
}
|
|
41
49
|
|
|
42
50
|
function getMismatchDisplayLines(anchorLines: readonly number[], fileLines: string[]): number[] {
|
|
@@ -62,6 +70,7 @@ export class MismatchError extends Error {
|
|
|
62
70
|
readonly actualFileHash: string;
|
|
63
71
|
readonly fileLines: string[];
|
|
64
72
|
readonly anchorLines: readonly number[];
|
|
73
|
+
readonly hashRecognized: boolean;
|
|
65
74
|
|
|
66
75
|
constructor(details: MismatchDetails) {
|
|
67
76
|
super(MismatchError.formatMessage(details));
|
|
@@ -71,6 +80,7 @@ export class MismatchError extends Error {
|
|
|
71
80
|
this.actualFileHash = details.actualFileHash;
|
|
72
81
|
this.fileLines = details.fileLines;
|
|
73
82
|
this.anchorLines = details.anchorLines ?? [];
|
|
83
|
+
this.hashRecognized = details.hashRecognized ?? true;
|
|
74
84
|
}
|
|
75
85
|
|
|
76
86
|
get displayMessage(): string {
|
|
@@ -80,14 +90,22 @@ export class MismatchError extends Error {
|
|
|
80
90
|
actualFileHash: this.actualFileHash,
|
|
81
91
|
fileLines: this.fileLines,
|
|
82
92
|
anchorLines: this.anchorLines,
|
|
93
|
+
hashRecognized: this.hashRecognized,
|
|
83
94
|
});
|
|
84
95
|
}
|
|
85
96
|
|
|
86
97
|
static rejectionHeader(details: MismatchDetails): string[] {
|
|
87
98
|
const pathText = details.path ? ` for ${details.path}` : "";
|
|
99
|
+
const hashRecognized = details.hashRecognized ?? true;
|
|
100
|
+
if (!hashRecognized) {
|
|
101
|
+
return [
|
|
102
|
+
`Edit rejected${pathText}: hash ${HL_FILE_HASH_SEP}${details.expectedFileHash} is not from this session.`,
|
|
103
|
+
`The current file hashes to ${HL_FILE_HASH_SEP}${details.actualFileHash}. Re-read the file with \`read\` to copy a current ${HL_FILE_PREFIX}path${HL_FILE_HASH_SEP}tag header — never invent the tag and never reuse one from a prior session.`,
|
|
104
|
+
];
|
|
105
|
+
}
|
|
88
106
|
return [
|
|
89
107
|
`Edit rejected${pathText}: file changed between read and edit.`,
|
|
90
|
-
`Section is bound to ${HL_FILE_HASH_SEP}${details.expectedFileHash}, but the current file hashes to ${HL_FILE_HASH_SEP}${details.actualFileHash}. If
|
|
108
|
+
`Section is bound to ${HL_FILE_HASH_SEP}${details.expectedFileHash}, but the current file hashes to ${HL_FILE_HASH_SEP}${details.actualFileHash}. If a prior edit in this session modified this file, copy the ${HL_FILE_PREFIX}path${HL_FILE_HASH_SEP}newhash header from that edit's response; otherwise re-read the file with \`read\` to refresh the tag before retrying.`,
|
|
91
109
|
];
|
|
92
110
|
}
|
|
93
111
|
|