@jerryan/pi-hashline-edit 0.7.1 → 0.7.3

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.
@@ -1,21 +1,11 @@
1
1
  /**
2
2
  * Edit response builders.
3
3
  *
4
- * Pulled out of `src/edit.ts` execute() so the noop and changed branches
5
- * are independently testable and the top-level execute path stays narrative.
6
- *
7
- * No behaviour change: outputs are byte-identical to the previous inline
8
- * implementation. The only additive surface is `details.metrics` (Phase 2 C
9
- * — observability for hosts; the LLM-visible text is unchanged).
4
+ * Unified diff output: agent and user see the same content. The diff is
5
+ * generated from structuredPatch hunks with hashline-formatted lines.
10
6
  */
11
7
 
12
8
  import { generateDiffString } from "./edit-diff";
13
- import {
14
- computeAffectedLineRange,
15
- formatHashlineRegion,
16
- } from "./hashline";
17
-
18
- const CHANGED_ANCHOR_TEXT_BUDGET_BYTES = 50 * 1024;
19
9
 
20
10
  // ─── Public types ───────────────────────────────────────────────────────
21
11
 
@@ -24,7 +14,6 @@ export type EditMetrics = {
24
14
  edits_noop: number;
25
15
  warnings: number;
26
16
  classification: "applied" | "noop";
27
- changed_lines?: { first: number; last: number };
28
17
  added_lines?: number;
29
18
  removed_lines?: number;
30
19
  };
@@ -51,8 +40,6 @@ export interface SuccessResponseInput {
51
40
  originalNormalized: string;
52
41
  result: string;
53
42
  warnings: string[] | undefined;
54
- firstChangedLine: number | undefined;
55
- lastChangedLine: number | undefined;
56
43
  snapshotId: string;
57
44
  editsAttempted: number;
58
45
  noopEditsCount: number;
@@ -60,12 +47,6 @@ export interface SuccessResponseInput {
60
47
 
61
48
  // ─── Helpers ────────────────────────────────────────────────────────────
62
49
 
63
- function getVisibleLines(text: string): string[] {
64
- if (text.length === 0) return [];
65
- const lines = text.split("\n");
66
- return text.endsWith("\n") ? lines.slice(0, -1) : lines;
67
- }
68
-
69
50
  function countDiffLines(diff: string, marker: "+" | "-"): number {
70
51
  if (!diff) return 0;
71
52
  let count = 0;
@@ -82,8 +63,6 @@ function buildMetrics(args: {
82
63
  editsAttempted: number;
83
64
  noopEditsCount: number;
84
65
  warningsCount: number;
85
- firstChangedLine?: number;
86
- lastChangedLine?: number;
87
66
  addedLines?: number;
88
67
  removedLines?: number;
89
68
  }): EditMetrics {
@@ -93,16 +72,6 @@ function buildMetrics(args: {
93
72
  warnings: args.warningsCount,
94
73
  classification: args.classification,
95
74
  };
96
- if (
97
- args.classification === "applied" &&
98
- args.firstChangedLine !== undefined &&
99
- args.lastChangedLine !== undefined
100
- ) {
101
- metrics.changed_lines = {
102
- first: args.firstChangedLine,
103
- last: args.lastChangedLine,
104
- };
105
- }
106
75
  if (args.addedLines !== undefined) metrics.added_lines = args.addedLines;
107
76
  if (args.removedLines !== undefined) metrics.removed_lines = args.removedLines;
108
77
  return metrics;
@@ -145,7 +114,6 @@ export function buildNoopResponse(input: NoopResponseInput): ToolResult {
145
114
  content: [{ type: "text", text }],
146
115
  details: {
147
116
  diff: "",
148
- firstChangedLine: undefined,
149
117
  snapshotId,
150
118
  classification: "noop" as const,
151
119
  metrics,
@@ -154,42 +122,15 @@ export function buildNoopResponse(input: NoopResponseInput): ToolResult {
154
122
  }
155
123
 
156
124
  export function buildChangedResponse(input: SuccessResponseInput): ToolResult {
157
- const {
158
- result,
159
- warnings,
160
- firstChangedLine,
161
- lastChangedLine,
162
- snapshotId,
163
- originalNormalized,
164
- editsAttempted,
165
- noopEditsCount,
166
- } = input;
125
+ const { result, warnings, snapshotId, originalNormalized, editsAttempted, noopEditsCount } =
126
+ input;
167
127
 
168
128
  const diffResult = generateDiffString(originalNormalized, result);
169
129
  const addedLines = countDiffLines(diffResult.diff, "+");
170
130
  const removedLines = countDiffLines(diffResult.diff, "-");
171
131
  const warningsBlock = warningsBlockOf(warnings);
172
132
 
173
- const resultLines = getVisibleLines(result);
174
- const anchorRange = computeAffectedLineRange({
175
- firstChangedLine,
176
- lastChangedLine,
177
- resultLineCount: resultLines.length,
178
- });
179
- const anchorsBlock = anchorRange
180
- ? (() => {
181
- const region = resultLines.slice(anchorRange.start - 1, anchorRange.end);
182
- const formatted = formatHashlineRegion(region, anchorRange.start);
183
- const block = `--- Anchors ${anchorRange.start}-${anchorRange.end} ---\n${formatted}`;
184
- return Buffer.byteLength(block, "utf8") <= CHANGED_ANCHOR_TEXT_BUDGET_BYTES
185
- ? block
186
- : "Anchors omitted; use read for subsequent edits.";
187
- })()
188
- : resultLines.length === 0
189
- ? "File is empty. Use edit with prepend or append and omit pos to insert content."
190
- : "Anchors omitted; use read for subsequent edits.";
191
-
192
- const text = [anchorsBlock, warningsBlock.trimStart()]
133
+ const text = [diffResult.diff, warningsBlock.trimStart()]
193
134
  .filter((section) => section.length > 0)
194
135
  .join("\n\n");
195
136
 
@@ -198,8 +139,6 @@ export function buildChangedResponse(input: SuccessResponseInput): ToolResult {
198
139
  editsAttempted,
199
140
  noopEditsCount,
200
141
  warningsCount: warnings?.length ?? 0,
201
- firstChangedLine,
202
- lastChangedLine,
203
142
  addedLines,
204
143
  removedLines,
205
144
  });
@@ -208,7 +147,6 @@ export function buildChangedResponse(input: SuccessResponseInput): ToolResult {
208
147
  content: [{ type: "text", text }],
209
148
  details: {
210
149
  diff: diffResult.diff,
211
- firstChangedLine: firstChangedLine ?? diffResult.firstChangedLine,
212
150
  snapshotId,
213
151
  metrics,
214
152
  },