pi-hashline-edit-pro 6.5.0 → 7.0.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 +59 -60
- package/package.json +2 -2
- package/src/anchor-registry.ts +15 -22
- package/src/auto-read-all.ts +2 -2
- package/src/constants.ts +1 -1
- package/src/copy-move.ts +11 -10
- package/src/edit-common.ts +11 -20
- package/src/edit-fidelity.ts +20 -1
- package/src/grep.ts +1 -10
- package/src/hashline/alphabet.ts +3 -3
- package/src/hashline/anchor-table.json +1 -1
- package/src/hashline/parse.ts +21 -14
- package/src/hashline/resolve.ts +23 -9
- package/src/insert.ts +9 -13
- package/src/payload-contract.ts +30 -22
- package/src/prompts.ts +1 -1
- package/src/read.ts +4 -6
- package/src/replace-diff.ts +1 -1
- package/src/replace-match.ts +36 -28
- package/src/replace-response.ts +5 -4
- package/src/replace.ts +12 -2
- package/src/write-hook.ts +4 -3
- package/tool-prompts/copy-guidelines.md +1 -1
- package/tool-prompts/copy.md +1 -1
- package/tool-prompts/grep-guidelines.md +1 -2
- package/tool-prompts/grep.md +1 -1
- package/tool-prompts/insert.md +1 -1
- package/tool-prompts/move.md +2 -2
- package/tool-prompts/read.md +1 -1
- package/tool-prompts/replace-match-guidelines.md +1 -1
- package/tool-prompts/replace-match-snippet.md +1 -1
- package/tool-prompts/replace-match.md +1 -1
- package/tool-prompts/replace.md +1 -1
- package/tool-prompts/transfer-guidelines.md +1 -1
package/src/edit-fidelity.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isBlankLine, splitLines } from "./utils";
|
|
2
|
-
import { HASH_SEP, canon } from "./hashline";
|
|
2
|
+
import { HASH_CLASS, HASH_SEP, canon } from "./hashline";
|
|
3
3
|
import type { DiffSpan } from "./replace-diff";
|
|
4
4
|
|
|
5
5
|
const INVISIBLE_RE = /\p{Default_Ignorable_Code_Point}/u;
|
|
@@ -396,6 +396,25 @@ export function annotateLiteralEscapeHints(
|
|
|
396
396
|
});
|
|
397
397
|
}
|
|
398
398
|
|
|
399
|
+
const LITERAL_ESCAPE_DETAIL_RE = /^\[H_LITERAL_ESCAPE\] [^:]*: "(.*?)" written as literal text(?: \((.*)\))?\.?$/;
|
|
400
|
+
const LITERAL_ESCAPE_ANCHOR_RE = new RegExp(`(${HASH_CLASS})│`, "g");
|
|
401
|
+
const UNICODE_LOST_DETAIL_RE = new RegExp(`^\\[H_UNICODE_LOST\\] (${HASH_CLASS})│ missing "([^"]*)"`);
|
|
402
|
+
|
|
403
|
+
export function dedupeLiteralEscapeHints(hints: readonly string[]): string[] {
|
|
404
|
+
const suppressed = new Set<string>();
|
|
405
|
+
for (const hint of hints) {
|
|
406
|
+
const literal = LITERAL_ESCAPE_DETAIL_RE.exec(hint);
|
|
407
|
+
if (literal === null) continue;
|
|
408
|
+
const escape = literal[1] ?? "";
|
|
409
|
+
for (const anchor of (literal[2] ?? "").matchAll(LITERAL_ESCAPE_ANCHOR_RE)) suppressed.add(`${anchor[1]}\0${escape}`);
|
|
410
|
+
}
|
|
411
|
+
if (suppressed.size === 0) return [...hints];
|
|
412
|
+
return hints.filter((hint) => {
|
|
413
|
+
const lost = UNICODE_LOST_DETAIL_RE.exec(hint);
|
|
414
|
+
return lost === null || !suppressed.has(`${lost[1]}\0${lost[2]}`);
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
|
|
399
418
|
function separatorLostHint(oldLines: string[], span: DiffSpan, originalHashes?: readonly string[]): string | undefined {
|
|
400
419
|
if (span.replacementCount !== 0 || span.end < span.start) return undefined;
|
|
401
420
|
const beforeIndex = span.start - 1;
|
package/src/grep.ts
CHANGED
|
@@ -70,14 +70,6 @@ function regexSource(pattern: string, literal: boolean): string {
|
|
|
70
70
|
return literal ? pattern.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") : pattern;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
function assertPattern(pattern: string, literal: boolean, ignoreCase: boolean): void {
|
|
74
|
-
try {
|
|
75
|
-
new RegExp(regexSource(pattern, literal), ignoreCase ? "ui" : "u");
|
|
76
|
-
} catch {
|
|
77
|
-
throw new Error(`[E_BAD_SHAPE] Invalid pattern: ${pattern}`);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
73
|
interface RgMatchLine {
|
|
82
74
|
line: number;
|
|
83
75
|
start: number;
|
|
@@ -393,7 +385,7 @@ const grepToolSchema = Type.Object(
|
|
|
393
385
|
limit: Type.Optional(
|
|
394
386
|
Type.Integer({
|
|
395
387
|
minimum: 1,
|
|
396
|
-
description: "Maximum number of matched lines to return",
|
|
388
|
+
description: "Maximum number of matched lines to return (default 100)",
|
|
397
389
|
}),
|
|
398
390
|
),
|
|
399
391
|
},
|
|
@@ -524,7 +516,6 @@ export function regGrep(pi: ExtensionAPI, flags: EditToolFlags = DEFAULT_EDIT_FL
|
|
|
524
516
|
const globPath = toDisplayPath(globRoot, absPath);
|
|
525
517
|
return globRegex.test(globPath) || globRegex.test(displayPath);
|
|
526
518
|
};
|
|
527
|
-
assertPattern(req.pattern, req.literal === true, req.ignoreCase === true);
|
|
528
519
|
const rgPath = await resolveRgPath();
|
|
529
520
|
const hits: FileHit[] = [];
|
|
530
521
|
let matches = 0;
|
package/src/hashline/alphabet.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import anchorData from "./anchor-table.json";
|
|
2
2
|
const rawAnchors: unknown = (anchorData as { anchors?: unknown }).anchors;
|
|
3
|
-
if (typeof rawAnchors !== "string" || rawAnchors.length === 0 || rawAnchors.length %
|
|
3
|
+
if (typeof rawAnchors !== "string" || rawAnchors.length === 0 || rawAnchors.length % 5 !== 0) {
|
|
4
4
|
throw new Error("[E_REGISTRY] Anchor table is missing or corrupt; reinstall pi-hashline-edit-pro.");
|
|
5
5
|
}
|
|
6
6
|
const TABLE: string = rawAnchors;
|
|
7
|
-
export const HASH_LEN =
|
|
7
|
+
export const HASH_LEN = 5;
|
|
8
8
|
export const ANCHOR_COUNT = TABLE.length / HASH_LEN;
|
|
9
9
|
const LETTERS = "A-Za-z";
|
|
10
10
|
|
|
11
11
|
export const ALPH_RE = new RegExp(`^[${LETTERS}]+$`);
|
|
12
12
|
|
|
13
|
-
export const HASH_CLASS = `[
|
|
13
|
+
export const HASH_CLASS = `[a-z]{${HASH_LEN}}`;
|
|
14
14
|
|
|
15
15
|
export const HASH_RUN = `[${LETTERS}]{${HASH_LEN},${HASH_LEN + 1}}`;
|
|
16
16
|
|