pi-hashline-edit-pro 4.2.11 → 4.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/README.md +19 -11
- package/index.ts +29 -8
- package/package.json +1 -1
- package/src/anchor-registry.ts +21 -31
- package/src/auto-read-all.ts +305 -0
- package/src/batch.ts +3 -3
- package/src/commit.ts +10 -19
- package/src/config-ui.ts +2 -1
- package/src/config.ts +52 -29
- package/src/constants.ts +6 -0
- package/src/fs-write.ts +1 -1
- package/src/grep.ts +12 -18
- package/src/hash-store/cache.ts +0 -18
- package/src/hash-store/retry.ts +0 -4
- package/src/hash-store/validation.ts +0 -31
- package/src/hash-store.ts +22 -32
- package/src/hashline/apply.ts +2 -2
- package/src/hashline/hash.ts +7 -8
- package/src/hashline/index.ts +1 -0
- package/src/hashline/parse.ts +3 -16
- package/src/hashline/resolve.ts +19 -39
- package/src/payload-contract.ts +3 -11
- package/src/read.ts +3 -3
- package/src/replace-diff.ts +107 -108
- package/src/replace-response.ts +37 -3
- package/src/replace-undo.ts +9 -9
- package/src/replace.ts +11 -5
- package/src/served.ts +7 -3
- package/src/utils.ts +9 -8
- package/src/write-hook.ts +0 -4
package/src/replace.ts
CHANGED
|
@@ -90,7 +90,14 @@ export function hashSpan(hashes: string[], from: string, to: string): [number, n
|
|
|
90
90
|
if (a < 0 || b < 0) return undefined;
|
|
91
91
|
return [Math.min(a, b), Math.max(a, b)];
|
|
92
92
|
}
|
|
93
|
-
|
|
93
|
+
|
|
94
|
+
export function spanForEdit(originalHashes: string[], from: string, to: string, resultContent: string): DiffSpan | undefined {
|
|
95
|
+
const span = hashSpan(originalHashes, from, to);
|
|
96
|
+
if (!span) return undefined;
|
|
97
|
+
const replacementCount = splitLines(resultContent).length - (originalHashes.length - (span[1] - span[0] + 1));
|
|
98
|
+
return { start: span[0], end: span[1], replacementCount };
|
|
99
|
+
}
|
|
100
|
+
async function noteAnchorError(absolutePath: string, error: unknown, noPersist?: boolean): Promise<void> {
|
|
94
101
|
if (noPersist === true) return;
|
|
95
102
|
if (error instanceof RangeStaleError) {
|
|
96
103
|
adoptAnchors(absolutePath, error.rangeServedMap);
|
|
@@ -159,7 +166,7 @@ export async function execPipeline(
|
|
|
159
166
|
strictBoundaryDedup,
|
|
160
167
|
);
|
|
161
168
|
} catch (error) {
|
|
162
|
-
await noteAnchorError(absolutePath, error,
|
|
169
|
+
await noteAnchorError(absolutePath, error, options?.noPersist);
|
|
163
170
|
throw error;
|
|
164
171
|
}
|
|
165
172
|
|
|
@@ -179,9 +186,8 @@ export async function execPipeline(
|
|
|
179
186
|
);
|
|
180
187
|
|
|
181
188
|
const sortedFixes = dedupRowsFromFixes(anchorResult.autoFixes ?? []);
|
|
182
|
-
const pipeSpan = isNoop ? undefined :
|
|
183
|
-
const
|
|
184
|
-
const pipeSpans = pipeSpan ? [{ start: pipeSpan[0], end: pipeSpan[1], replacementCount: pipeResultCount - (originalHashes.length - (pipeSpan[1] - pipeSpan[0] + 1)) }] : undefined;
|
|
189
|
+
const pipeSpan = isNoop ? undefined : spanForEdit(originalHashes, edit.hash_bounds[0].hash, edit.hash_bounds[1].hash, result);
|
|
190
|
+
const pipeSpans = pipeSpan ? [pipeSpan] : undefined;
|
|
185
191
|
return {
|
|
186
192
|
path: displayPath,
|
|
187
193
|
originalNormalized,
|
package/src/served.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { HASH_CLASS } from "./hashline/alphabet";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { lineChecksum } from "./hashline/hash";
|
|
3
|
+
import { markServed } from "./anchor-registry";
|
|
4
4
|
|
|
5
5
|
const SERVED_DIFF_ROW_RE = new RegExp(`^[+ ](${HASH_CLASS})│`);
|
|
6
6
|
|
|
@@ -26,7 +26,11 @@ export function buildServedMap(
|
|
|
26
26
|
const entries: Array<[string, string]> = [];
|
|
27
27
|
for (const hash of wantedHashes) {
|
|
28
28
|
const idx = index.get(hash);
|
|
29
|
-
if (idx !== undefined) entries.push([hash,
|
|
29
|
+
if (idx !== undefined) entries.push([hash, lineChecksum(fileLines[idx]!)]);
|
|
30
30
|
}
|
|
31
31
|
return entries;
|
|
32
32
|
}
|
|
33
|
+
|
|
34
|
+
export function serveRows(path: string, fileHashes: string[], fileLines: string[], wantedHashes: string[]): void {
|
|
35
|
+
markServed(path, buildServedMap(fileHashes, fileLines, wantedHashes), new Set(fileHashes));
|
|
36
|
+
}
|
package/src/utils.ts
CHANGED
|
@@ -22,14 +22,16 @@ export function normalizeAnchors(record: Record<string, unknown>): void {
|
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
export function normalizeRequest(input: unknown): unknown {
|
|
26
|
+
if (!isRec(input)) return input;
|
|
27
|
+
const record: Record<string, unknown> = { ...input };
|
|
28
|
+
normalizeFilePath(record);
|
|
29
|
+
normalizeAnchors(record);
|
|
30
|
+
return record;
|
|
31
|
+
}
|
|
32
|
+
|
|
25
33
|
export function makePrepareArguments(): (args: unknown) => any {
|
|
26
|
-
return
|
|
27
|
-
if (!isRec(args)) return args;
|
|
28
|
-
const record = { ...args };
|
|
29
|
-
normalizeFilePath(record);
|
|
30
|
-
normalizeAnchors(record);
|
|
31
|
-
return record;
|
|
32
|
-
};
|
|
34
|
+
return normalizeRequest;
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
export function splitLines(text: string): string[] {
|
|
@@ -293,7 +295,6 @@ export function decodeStringArray(value: unknown, warnings?: string[], label = "
|
|
|
293
295
|
if (candidate === undefined) return undefined;
|
|
294
296
|
const decoded = decodeArrayText(candidate);
|
|
295
297
|
if (decoded !== undefined) {
|
|
296
|
-
warnings?.push(`[W_BAD_SHAPE] Unwrapped JSON array syntax from a ${label} element.`);
|
|
297
298
|
return decoded;
|
|
298
299
|
}
|
|
299
300
|
if (looksLikeStringArray(candidate)) {
|
package/src/write-hook.ts
CHANGED
|
@@ -19,10 +19,6 @@ export function findServedHashEcho(content: string, served: ReadonlyMap<string,
|
|
|
19
19
|
return searchEcho(splitLines(content), served);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export function findEditHashEcho(lines: string[], served: ReadonlyMap<string, string> | ReadonlySet<string>): { line: number; hash: string } | undefined {
|
|
23
|
-
return searchEcho(lines, served);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
22
|
export async function servedHashEchoDenial(rawPath: string, content: string, cwd: string, signal?: AbortSignal): Promise<string | undefined> {
|
|
27
23
|
abortIf(signal);
|
|
28
24
|
const { resolved } = await resolveInCwd(rawPath, cwd);
|