@lmzhen/dsh-evolution-core 0.1.0-rc.19 → 0.1.0-rc.20

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.
Files changed (2) hide show
  1. package/lib/index.js +71 -4
  2. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -1435,12 +1435,79 @@ function validateSupportPath(filePath) {
1435
1435
  if (parts.length < 2) return "Provide a file name, not just a directory.";
1436
1436
  return null;
1437
1437
  }
1438
+ /**
1439
+ * Index of `pattern` inside `content`, treating whitespace runs (spaces/tabs)
1440
+ * as flexible and literal escape sequences (`\n`, `\t`, `\r`) as their real
1441
+ * characters: a whitespace run on either side matches a run of any length on
1442
+ * the other, and a backslash-escaped char in the pattern matches the real char
1443
+ * in the content (model-copy drift). Returns the [start, end) range in the
1444
+ * ORIGINAL content so a patch can replace exactly the matched span and keep
1445
+ * every other byte intact. Returns null when no fuzzy match exists.
1446
+ */
1447
+ function fuzzyIndexOf(content, pattern) {
1448
+ const isSpace = (char) => char !== void 0 && /[ \t]/.test(char);
1449
+ const escaped = (char) => {
1450
+ if (char === "n") return "\n";
1451
+ if (char === "t") return " ";
1452
+ if (char === "r") return "\r";
1453
+ return null;
1454
+ };
1455
+ for (let start = 0; start < content.length; start += 1) {
1456
+ let contentIndex = start;
1457
+ let patternIndex = 0;
1458
+ while (patternIndex < pattern.length && contentIndex < content.length) {
1459
+ const patternChar = pattern[patternIndex];
1460
+ const contentChar = content[contentIndex];
1461
+ if (isSpace(patternChar)) {
1462
+ while (patternIndex < pattern.length && isSpace(pattern[patternIndex])) patternIndex += 1;
1463
+ while (contentIndex < content.length && isSpace(content[contentIndex])) contentIndex += 1;
1464
+ continue;
1465
+ }
1466
+ const escapedChar = patternChar === "\\" ? escaped(pattern[patternIndex + 1]) : null;
1467
+ if (escapedChar !== null && contentChar === escapedChar) {
1468
+ patternIndex += 2;
1469
+ contentIndex += 1;
1470
+ continue;
1471
+ }
1472
+ if (patternChar === contentChar) {
1473
+ contentIndex += 1;
1474
+ patternIndex += 1;
1475
+ continue;
1476
+ }
1477
+ break;
1478
+ }
1479
+ if (patternIndex === pattern.length) return [start, contentIndex];
1480
+ }
1481
+ return null;
1482
+ }
1483
+ /** Trim leading whitespace of the first line and trailing whitespace of the last line. */
1484
+ function trimPatternBoundaries(pattern) {
1485
+ const from = pattern.search(/\S/);
1486
+ const trimmed = from < 0 ? pattern : pattern.slice(from);
1487
+ const trailing = trimmed.search(/\s+$/);
1488
+ return trailing < 0 ? trimmed : trimmed.slice(0, trailing);
1489
+ }
1490
+ /** Replace only the fuzzy-matched span, preserving all surrounding bytes. */
1491
+ function fuzzyReplace(content, oldString, newString, replaceAll) {
1492
+ const match = fuzzyIndexOf(content, oldString);
1493
+ if (match === null) return content;
1494
+ const [start, end] = match;
1495
+ const patched = content.slice(0, start) + newString + content.slice(end);
1496
+ return replaceAll ? fuzzyReplace(patched, oldString, newString, true) : patched;
1497
+ }
1438
1498
  function fuzzyPatch(content, oldString, newString, replaceAll = false) {
1439
1499
  if (content.includes(oldString)) return replaceAll ? content.split(oldString).join(newString) : content.replace(oldString, newString);
1440
- const trimmed = content.replaceAll(/[ ]+$/gm, "");
1441
- if (trimmed.includes(oldString)) return trimmed.replace(oldString, newString);
1442
- const whitespace = content.replaceAll(/[ ]+/g, " ");
1443
- if (whitespace.includes(oldString)) return whitespace.replace(oldString, newString);
1500
+ const boundary = trimPatternBoundaries(oldString);
1501
+ if (boundary !== oldString) {
1502
+ if (fuzzyIndexOf(content, boundary) !== null) {
1503
+ const patched = fuzzyReplace(content, boundary, newString, replaceAll);
1504
+ return patched === content ? null : patched;
1505
+ }
1506
+ }
1507
+ if (fuzzyIndexOf(content, oldString) !== null) {
1508
+ const patched = fuzzyReplace(content, oldString, newString, replaceAll);
1509
+ return patched === content ? null : patched;
1510
+ }
1444
1511
  return null;
1445
1512
  }
1446
1513
  var SkillLibrary = class {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lmzhen/dsh-evolution-core",
3
3
  "description": "Shared stores, prompts, signals and lifecycle logic for the dsh-evolution plugin family (community build)",
4
- "version": "0.1.0-rc.19",
4
+ "version": "0.1.0-rc.20",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },