@adeu/core 1.18.0 → 1.18.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adeu/core",
3
- "version": "1.18.0",
3
+ "version": "1.18.1",
4
4
  "description": "",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -31,7 +31,11 @@ describe("Feedback Layer & Dry Run Verification", () => {
31
31
  expect(stats.version).toBeDefined();
32
32
  });
33
33
 
34
- it("punctuation anchor triggers warning", async () => {
34
+ it("punctuation anchor: no warning on clean apply", async () => {
35
+ // A punctuated anchor that matches and applies cleanly must NOT raise the
36
+ // tokenization-splitting warning. The redline preview already reports the
37
+ // change; a warning here is a false positive that pushes agents into
38
+ // needless "cleaner anchor" retries.
35
39
  const doc = await createTestDocument();
36
40
  addParagraph(doc, "Refer to sample_term_name in Section 4.");
37
41
  const engine = new RedlineEngine(doc, "Reviewer TS");
@@ -41,9 +45,37 @@ describe("Feedback Layer & Dry Run Verification", () => {
41
45
  ]);
42
46
 
43
47
  const report = stats.edits[0];
48
+ expect(report.status).toBe("applied");
49
+ expect(report.warning).toBeNull();
50
+
51
+ // Same expectation under dry_run.
52
+ const doc2 = await createTestDocument();
53
+ addParagraph(doc2, "Refer to sample_term_name in Section 4.");
54
+ const engine2 = new RedlineEngine(doc2, "Reviewer TS");
55
+ const dryStats = (engine2 as any).process_batch([
56
+ { type: "modify", target_text: "sample_term_name", new_text: "validated_term_name" }
57
+ ], true);
58
+ const dryReport = dryStats.edits[0];
59
+ expect(dryReport.status).toBe("applied");
60
+ expect(dryReport.warning).toBeNull();
61
+ });
62
+
63
+ it("punctuation anchor: warns only when match fails", async () => {
64
+ // When a punctuated anchor fails to match, the warning IS surfaced as
65
+ // recovery context (the punctuation may be why the match missed).
66
+ const doc = await createTestDocument();
67
+ addParagraph(doc, "Refer to sample_term_name in Section 4.");
68
+ const engine = new RedlineEngine(doc, "Reviewer TS");
69
+
70
+ const stats = (engine as any).process_batch([
71
+ { type: "modify", target_text: "phantom_term-x", new_text: "anything" }
72
+ ], true);
73
+
74
+ const report = stats.edits[0];
75
+ expect(report.status).toBe("failed");
44
76
  expect(report.warning).not.toBeNull();
45
77
  expect(report.warning.toLowerCase()).toContain("punctuation");
46
- expect(report.warning).toContain("sample_term_name");
78
+ expect(report.warning).toContain("phantom_term-x");
47
79
  });
48
80
 
49
81
  it("dry_run does not mutate and reports safely", async () => {
package/src/engine.ts CHANGED
@@ -322,8 +322,19 @@ export class RedlineEngine {
322
322
  this.comments_manager = new CommentsManager(this.doc);
323
323
  }
324
324
 
325
+ /**
326
+ * Return a hint when a short, single-token anchor contains punctuation that
327
+ * can split awkwardly, else null.
328
+ *
329
+ * Surface this ONLY for edits that actually failed to match/apply. On a
330
+ * successful edit the batch report already carries the redline preview, so
331
+ * emitting this would be a false positive: the punctuation (dates,
332
+ * `[_name_]` placeholders, `____` blanks) is frequently the literal target
333
+ * and the edit succeeds despite it. Mirrors the Python engine.
334
+ */
325
335
  private _check_punctuation_warning(target_text: string): string | null {
326
336
  if (!target_text) return null;
337
+ if (target_text.length > 20 || target_text.includes(" ")) return null;
327
338
  if (target_text.includes("_") || target_text.includes("-")) {
328
339
  return `Warning: target_text '${target_text}' contains tokenization-splitting punctuation ('_' or '-'). This can trigger mid-word splits in the diff engine. Consider using a longer plain-prose anchor.`;
329
340
  }
@@ -1894,11 +1905,16 @@ export class RedlineEngine {
1894
1905
  for (let i = 0; i < edits.length; i++) {
1895
1906
  const edit = edits[i];
1896
1907
  const single_errors = this.validate_edits([edit], i);
1897
- const warning = this._check_punctuation_warning(
1898
- (edit as any).target_text || "",
1899
- );
1900
1908
  if (single_errors.length > 0) {
1901
1909
  skipped_edits++;
1910
+ // Only surface the punctuation-anchor warning when the edit actually
1911
+ // failed. A clean apply already returns the redline preview, so the
1912
+ // warning is pure noise on success — and it misleads agents into
1913
+ // hunting for a "cleaner" anchor that was never needed (e.g. on
1914
+ // placeholders/dates where the punctuation IS the literal target).
1915
+ const warning = this._check_punctuation_warning(
1916
+ (edit as any).target_text || "",
1917
+ );
1902
1918
  edits_reports.push({
1903
1919
  status: "failed",
1904
1920
  target_text: (edit as any).target_text || "",
@@ -1918,7 +1934,7 @@ export class RedlineEngine {
1918
1934
  status: "applied",
1919
1935
  target_text: (edit as any).target_text || "",
1920
1936
  new_text: (edit as any).new_text || "",
1921
- warning: warning,
1937
+ warning: null,
1922
1938
  error: null,
1923
1939
  critic_markup: previews[0],
1924
1940
  clean_text: previews[1],
@@ -1935,6 +1951,9 @@ export class RedlineEngine {
1935
1951
  this.skipped_details.length > 0
1936
1952
  ? this.skipped_details[this.skipped_details.length - 1]
1937
1953
  : "Failed to apply edit";
1954
+ const warning = this._check_punctuation_warning(
1955
+ (edit as any).target_text || "",
1956
+ );
1938
1957
  edits_reports.push({
1939
1958
  status: "failed",
1940
1959
  target_text: (edit as any).target_text || "",
@@ -1983,15 +2002,19 @@ export class RedlineEngine {
1983
2002
  for (const edit of edits) {
1984
2003
  const success = (edit as any)._applied_status || false;
1985
2004
  const error_msg = (edit as any)._error_msg || null;
1986
- const warning = this._check_punctuation_warning(
1987
- (edit as any).target_text || "",
1988
- );
1989
2005
  let critic_markup = null;
1990
2006
  let clean_text = null;
2007
+ // Punctuation-anchor warning is failure-context only: on success the
2008
+ // redline preview below already reports the change cleanly.
2009
+ let warning: string | null = null;
1991
2010
  if (success) {
1992
2011
  const previews = this._build_edit_context_previews(edit);
1993
2012
  critic_markup = previews[0];
1994
2013
  clean_text = previews[1];
2014
+ } else {
2015
+ warning = this._check_punctuation_warning(
2016
+ (edit as any).target_text || "",
2017
+ );
1995
2018
  }
1996
2019
  edits_reports.push({
1997
2020
  status: success ? "applied" : "failed",