@wrongstack/tools 0.283.1 → 0.284.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/dist/audit.js.map +1 -1
- package/dist/bash.js +4 -0
- package/dist/bash.js.map +1 -1
- package/dist/builtin.js +685 -253
- package/dist/builtin.js.map +1 -1
- package/dist/codebase-index/index.js +2 -2
- package/dist/codebase-index/index.js.map +1 -1
- package/dist/diff.js.map +1 -1
- package/dist/document.js.map +1 -1
- package/dist/edit.d.ts +43 -0
- package/dist/edit.js +386 -60
- package/dist/edit.js.map +1 -1
- package/dist/{exec-Ca3fnpUh.d.ts → exec-2OKoT6tk.d.ts} +1 -1
- package/dist/exec.d.ts +1 -1
- package/dist/exec.js +13 -14
- package/dist/exec.js.map +1 -1
- package/dist/fetch.js.map +1 -1
- package/dist/format.js.map +1 -1
- package/dist/git.js.map +1 -1
- package/dist/glob.js +10 -1
- package/dist/glob.js.map +1 -1
- package/dist/grep.js +4 -0
- package/dist/grep.js.map +1 -1
- package/dist/index.d.ts +13 -2
- package/dist/index.js +730 -268
- package/dist/index.js.map +1 -1
- package/dist/install.js.map +1 -1
- package/dist/json.js.map +1 -1
- package/dist/lint.js.map +1 -1
- package/dist/logs.js.map +1 -1
- package/dist/next-steps.d.ts +66 -0
- package/dist/next-steps.js +116 -0
- package/dist/next-steps.js.map +1 -0
- package/dist/outdated.js.map +1 -1
- package/dist/pack.js +685 -253
- package/dist/pack.js.map +1 -1
- package/dist/patch.js +43 -0
- package/dist/patch.js.map +1 -1
- package/dist/read.js +13 -4
- package/dist/read.js.map +1 -1
- package/dist/replace.js +14 -0
- package/dist/replace.js.map +1 -1
- package/dist/scaffold.js.map +1 -1
- package/dist/test.js.map +1 -1
- package/dist/tool-diff.d.ts +88 -0
- package/dist/tool-diff.js +229 -0
- package/dist/tool-diff.js.map +1 -0
- package/dist/tool-summary.d.ts +24 -0
- package/dist/tool-summary.js +208 -0
- package/dist/tool-summary.js.map +1 -0
- package/dist/tree.js.map +1 -1
- package/dist/typecheck.js.map +1 -1
- package/dist/write.d.ts +6 -0
- package/dist/write.js +118 -19
- package/dist/write.js.map +1 -1
- package/package.json +15 -2
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/** A single rendered diff line. */
|
|
2
|
+
type DiffRowKind = 'add' | 'del' | 'ctx' | 'meta';
|
|
3
|
+
interface DiffRow {
|
|
4
|
+
kind: DiffRowKind;
|
|
5
|
+
text: string;
|
|
6
|
+
}
|
|
7
|
+
/** Extraction result: enough for a caller to render without re-inspecting input. */
|
|
8
|
+
type ToolDiff = {
|
|
9
|
+
mode: 'lcs';
|
|
10
|
+
oldText: string;
|
|
11
|
+
newText: string;
|
|
12
|
+
caption: string;
|
|
13
|
+
} | {
|
|
14
|
+
mode: 'unified';
|
|
15
|
+
patchText: string;
|
|
16
|
+
caption: string;
|
|
17
|
+
};
|
|
18
|
+
/** Max lines per side before we bail out of the O(n*m) LCS table. */
|
|
19
|
+
declare const DIFF_MAX_LINES = 5000;
|
|
20
|
+
/**
|
|
21
|
+
* Recognise the edit-family tools and pull a renderable diff descriptor out of
|
|
22
|
+
* their input. Returns null when the tool doesn't carry diffable input.
|
|
23
|
+
*
|
|
24
|
+
* @param toolName canonical or aliased tool name.
|
|
25
|
+
* @param input tool input — a parsed object OR a JSON string.
|
|
26
|
+
*/
|
|
27
|
+
declare function diffFromToolInput(toolName: string | undefined, input: unknown): ToolDiff | null;
|
|
28
|
+
/**
|
|
29
|
+
* LCS-based line diff. Returns null when either side exceeds DIFF_MAX_LINES
|
|
30
|
+
* (an O(n*m) memory guard — fine for a normal edit, prohibitive for a huge
|
|
31
|
+
* generated-file rewrite).
|
|
32
|
+
*/
|
|
33
|
+
declare function computeLineDiff(oldText: string, newText: string): DiffRow[] | null;
|
|
34
|
+
/**
|
|
35
|
+
* Parse a unified-diff string into renderable rows. Hunk headers (`@@ ... @@`)
|
|
36
|
+
* and file headers (`--- `, `+++ `, `diff `, `index `) become `meta` rows; body
|
|
37
|
+
* lines map to add/del/ctx by their leading char. ``
|
|
38
|
+
* is kept as a meta row.
|
|
39
|
+
*/
|
|
40
|
+
declare function parseUnifiedDiff(patchText: string): DiffRow[];
|
|
41
|
+
/**
|
|
42
|
+
* Convenience: extract + render to rows in one call. Returns null when the tool
|
|
43
|
+
* carries no diffable input, or `{ caption, rows: null }` when the diff is too
|
|
44
|
+
* large to render (LCS guard).
|
|
45
|
+
*/
|
|
46
|
+
declare function diffRowsFromToolInput(toolName: string | undefined, input: unknown): {
|
|
47
|
+
caption: string;
|
|
48
|
+
rows: DiffRow[] | null;
|
|
49
|
+
} | null;
|
|
50
|
+
/** Rich diff row: like DiffRow but with a dedicated `hunk` kind and gutters. */
|
|
51
|
+
type DiffLineKind = 'add' | 'del' | 'hunk' | 'ctx' | 'meta';
|
|
52
|
+
interface DiffLineRow {
|
|
53
|
+
kind: DiffLineKind;
|
|
54
|
+
text: string;
|
|
55
|
+
oldLine?: number | undefined;
|
|
56
|
+
newLine?: number | undefined;
|
|
57
|
+
}
|
|
58
|
+
/** A parsed unified-diff preview: rows plus visible/hidden tallies. */
|
|
59
|
+
interface DiffPreview {
|
|
60
|
+
rows: DiffLineRow[];
|
|
61
|
+
hidden: number;
|
|
62
|
+
added: number;
|
|
63
|
+
removed: number;
|
|
64
|
+
hiddenAdded: number;
|
|
65
|
+
hiddenRemoved: number;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Safety cap on a single diff row's stored text — guards against pathological
|
|
69
|
+
* one-line files (minified bundles, huge JSON) flooding a consumer. Real code
|
|
70
|
+
* lines are never truncated at this length.
|
|
71
|
+
*/
|
|
72
|
+
declare const DIFF_LINE_SAFETY_CAP = 4000;
|
|
73
|
+
/** Truncate the middle-out: keep the head, append an ellipsis, past `max`. */
|
|
74
|
+
declare function truncMid(s: string, max: number): string;
|
|
75
|
+
/**
|
|
76
|
+
* Parse a unified-diff string into a {@link DiffPreview} with per-row line
|
|
77
|
+
* numbers and add/remove tallies. `maxLines` caps the visible rows; the rest
|
|
78
|
+
* fold into `hidden`/`hiddenAdded`/`hiddenRemoved`. Pass
|
|
79
|
+
* `Number.POSITIVE_INFINITY` to render everything.
|
|
80
|
+
*
|
|
81
|
+
* This is the richer sibling of {@link parseUnifiedDiff}: it keeps a dedicated
|
|
82
|
+
* `hunk` kind (rather than folding hunk headers into `meta`) and tracks old/new
|
|
83
|
+
* line gutters, which a terminal/gutter renderer needs.
|
|
84
|
+
*/
|
|
85
|
+
declare function parseUnifiedDiffPreview(diff: string, maxLines: number, lineCap?: number): DiffPreview;
|
|
86
|
+
declare const TOOL_DIFF_BROWSER_SRC: string;
|
|
87
|
+
|
|
88
|
+
export { DIFF_LINE_SAFETY_CAP, DIFF_MAX_LINES, type DiffLineKind, type DiffLineRow, type DiffPreview, type DiffRow, type DiffRowKind, TOOL_DIFF_BROWSER_SRC, type ToolDiff, computeLineDiff, diffFromToolInput, diffRowsFromToolInput, parseUnifiedDiff, parseUnifiedDiffPreview, truncMid };
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
// src/tool-diff.ts
|
|
2
|
+
var DIFF_MAX_LINES = 5e3;
|
|
3
|
+
function asObject(input) {
|
|
4
|
+
if (typeof input === "string") {
|
|
5
|
+
const s = input.trim();
|
|
6
|
+
if (s.startsWith("{") || s.startsWith("[")) {
|
|
7
|
+
try {
|
|
8
|
+
const parsed = JSON.parse(s);
|
|
9
|
+
if (parsed && typeof parsed === "object") return parsed;
|
|
10
|
+
} catch {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
if (input && typeof input === "object") return input;
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
function diffFromToolInput(toolName, input) {
|
|
20
|
+
if (!toolName) return null;
|
|
21
|
+
const obj = asObject(input);
|
|
22
|
+
if (!obj) return null;
|
|
23
|
+
const name = toolName.toLowerCase();
|
|
24
|
+
const filePath = String(obj.file_path ?? obj.path ?? "");
|
|
25
|
+
switch (name) {
|
|
26
|
+
case "edit":
|
|
27
|
+
case "str_replace":
|
|
28
|
+
case "edit_file":
|
|
29
|
+
case "multi_edit": {
|
|
30
|
+
const oldText = typeof obj.old_string === "string" ? obj.old_string : "";
|
|
31
|
+
const newText = typeof obj.new_string === "string" ? obj.new_string : "";
|
|
32
|
+
if (!oldText && !newText) return null;
|
|
33
|
+
return { mode: "lcs", oldText, newText, caption: `edit ${filePath}`.trim() };
|
|
34
|
+
}
|
|
35
|
+
case "write":
|
|
36
|
+
case "write_file":
|
|
37
|
+
case "create_file": {
|
|
38
|
+
const content = typeof obj.content === "string" ? obj.content : "";
|
|
39
|
+
if (!content) return null;
|
|
40
|
+
return { mode: "lcs", oldText: "", newText: content, caption: `write ${filePath} (new)`.trim() };
|
|
41
|
+
}
|
|
42
|
+
case "patch": {
|
|
43
|
+
const patchText = typeof obj.patch === "string" ? obj.patch : "";
|
|
44
|
+
if (!patchText.trim()) return null;
|
|
45
|
+
return { mode: "unified", patchText, caption: filePath ? `patch ${filePath}` : "patch" };
|
|
46
|
+
}
|
|
47
|
+
default:
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function computeLineDiff(oldText, newText) {
|
|
52
|
+
const a = oldText.split("\n");
|
|
53
|
+
const b = newText.split("\n");
|
|
54
|
+
if (a.length > DIFF_MAX_LINES || b.length > DIFF_MAX_LINES) return null;
|
|
55
|
+
const n = a.length;
|
|
56
|
+
const m = b.length;
|
|
57
|
+
const dp = Array.from({ length: n + 1 }, () => new Array(m + 1).fill(0));
|
|
58
|
+
for (let i2 = n - 1; i2 >= 0; i2--) {
|
|
59
|
+
for (let j2 = m - 1; j2 >= 0; j2--) {
|
|
60
|
+
dp[i2][j2] = a[i2] === b[j2] ? dp[i2 + 1][j2 + 1] + 1 : Math.max(dp[i2 + 1][j2], dp[i2][j2 + 1]);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const rows = [];
|
|
64
|
+
let i = 0;
|
|
65
|
+
let j = 0;
|
|
66
|
+
while (i < n && j < m) {
|
|
67
|
+
if (a[i] === b[j]) {
|
|
68
|
+
rows.push({ kind: "ctx", text: a[i] });
|
|
69
|
+
i++;
|
|
70
|
+
j++;
|
|
71
|
+
} else if (dp[i + 1][j] >= dp[i][j + 1]) {
|
|
72
|
+
rows.push({ kind: "del", text: a[i] });
|
|
73
|
+
i++;
|
|
74
|
+
} else {
|
|
75
|
+
rows.push({ kind: "add", text: b[j] });
|
|
76
|
+
j++;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
while (i < n) rows.push({ kind: "del", text: a[i++] });
|
|
80
|
+
while (j < m) rows.push({ kind: "add", text: b[j++] });
|
|
81
|
+
return rows;
|
|
82
|
+
}
|
|
83
|
+
function parseUnifiedDiff(patchText) {
|
|
84
|
+
const rows = [];
|
|
85
|
+
const lines = patchText.split("\n");
|
|
86
|
+
for (const raw of lines) {
|
|
87
|
+
if (raw.startsWith("@@") || raw.startsWith("--- ") || raw.startsWith("+++ ") || raw.startsWith("diff ") || raw.startsWith("index ") || raw.startsWith("\\ ")) {
|
|
88
|
+
rows.push({ kind: "meta", text: raw });
|
|
89
|
+
} else if (raw.startsWith("+")) {
|
|
90
|
+
rows.push({ kind: "add", text: raw.slice(1) });
|
|
91
|
+
} else if (raw.startsWith("-")) {
|
|
92
|
+
rows.push({ kind: "del", text: raw.slice(1) });
|
|
93
|
+
} else {
|
|
94
|
+
rows.push({ kind: "ctx", text: raw.startsWith(" ") ? raw.slice(1) : raw });
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (rows.length > 0 && rows[rows.length - 1].kind === "ctx" && rows[rows.length - 1].text === "") {
|
|
98
|
+
rows.pop();
|
|
99
|
+
}
|
|
100
|
+
return rows;
|
|
101
|
+
}
|
|
102
|
+
function diffRowsFromToolInput(toolName, input) {
|
|
103
|
+
const d = diffFromToolInput(toolName, input);
|
|
104
|
+
if (!d) return null;
|
|
105
|
+
if (d.mode === "unified") return { caption: d.caption, rows: parseUnifiedDiff(d.patchText) };
|
|
106
|
+
return { caption: d.caption, rows: computeLineDiff(d.oldText, d.newText) };
|
|
107
|
+
}
|
|
108
|
+
var DIFF_LINE_SAFETY_CAP = 4e3;
|
|
109
|
+
function truncMid(s, max) {
|
|
110
|
+
if (s.length <= max) return s;
|
|
111
|
+
return `${s.slice(0, max - 1)}\u2026`;
|
|
112
|
+
}
|
|
113
|
+
function parseUnifiedDiffPreview(diff, maxLines, lineCap = DIFF_LINE_SAFETY_CAP) {
|
|
114
|
+
const all = [];
|
|
115
|
+
let oldLn = 0;
|
|
116
|
+
let newLn = 0;
|
|
117
|
+
for (const raw of diff.split("\n")) {
|
|
118
|
+
const line = raw.replace(/\r$/, "");
|
|
119
|
+
if (line.startsWith("+++") || line.startsWith("---")) continue;
|
|
120
|
+
if (line.startsWith("diff --git") || line.startsWith("index ")) continue;
|
|
121
|
+
if (line.startsWith("@@")) {
|
|
122
|
+
const m = line.match(/^@@\s+-(\d+)(?:,\d+)?\s+\+(\d+)(?:,\d+)?\s+@@/);
|
|
123
|
+
if (m) {
|
|
124
|
+
oldLn = Number.parseInt(m[1] ?? "0", 10) || 0;
|
|
125
|
+
newLn = Number.parseInt(m[2] ?? "0", 10) || 0;
|
|
126
|
+
}
|
|
127
|
+
all.push({ kind: "hunk", text: truncMid(line, 60) });
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (line.startsWith("+")) {
|
|
131
|
+
all.push({ kind: "add", text: truncMid(line, lineCap), newLine: newLn });
|
|
132
|
+
newLn++;
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
if (line.startsWith("-")) {
|
|
136
|
+
all.push({ kind: "del", text: truncMid(line, lineCap), oldLine: oldLn });
|
|
137
|
+
oldLn++;
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
if (line.startsWith("\\ No newline")) {
|
|
141
|
+
all.push({ kind: "meta", text: line });
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
if (line.length === 0) continue;
|
|
145
|
+
all.push({ kind: "ctx", text: truncMid(line, lineCap), oldLine: oldLn, newLine: newLn });
|
|
146
|
+
oldLn++;
|
|
147
|
+
newLn++;
|
|
148
|
+
}
|
|
149
|
+
const added = all.filter((row) => row.kind === "add").length;
|
|
150
|
+
const removed = all.filter((row) => row.kind === "del").length;
|
|
151
|
+
if (all.length === 0) {
|
|
152
|
+
return { rows: [], hidden: 0, added: 0, removed: 0, hiddenAdded: 0, hiddenRemoved: 0 };
|
|
153
|
+
}
|
|
154
|
+
if (all.length <= maxLines) {
|
|
155
|
+
return { rows: all, hidden: 0, added, removed, hiddenAdded: 0, hiddenRemoved: 0 };
|
|
156
|
+
}
|
|
157
|
+
const rows = all.slice(0, maxLines);
|
|
158
|
+
const hiddenRows = all.slice(maxLines);
|
|
159
|
+
return {
|
|
160
|
+
rows,
|
|
161
|
+
hidden: hiddenRows.length,
|
|
162
|
+
added,
|
|
163
|
+
removed,
|
|
164
|
+
hiddenAdded: hiddenRows.filter((row) => row.kind === "add").length,
|
|
165
|
+
hiddenRemoved: hiddenRows.filter((row) => row.kind === "del").length
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
var TOOL_DIFF_BROWSER_SRC = [
|
|
169
|
+
"var DIFF_MAX_LINES = 5000;",
|
|
170
|
+
"function __diffObj(input){",
|
|
171
|
+
' if(typeof input==="string"){ var s=input.trim(); if(s.charAt(0)==="{"||s.charAt(0)==="["){ try{ var p=JSON.parse(s); if(p&&typeof p==="object") return p; }catch(_e){} } return null; }',
|
|
172
|
+
' if(input&&typeof input==="object") return input; return null;',
|
|
173
|
+
"}",
|
|
174
|
+
"function diffFromToolInput(name, input){",
|
|
175
|
+
" if(!name) return null;",
|
|
176
|
+
" var obj=__diffObj(input); if(!obj) return null;",
|
|
177
|
+
" var n=String(name).toLowerCase();",
|
|
178
|
+
' var fp=String(obj.file_path!=null?obj.file_path:(obj.path!=null?obj.path:""));',
|
|
179
|
+
' if(n==="edit"||n==="str_replace"||n==="edit_file"||n==="multi_edit"){',
|
|
180
|
+
' var oldT=typeof obj.old_string==="string"?obj.old_string:"";',
|
|
181
|
+
' var newT=typeof obj.new_string==="string"?obj.new_string:"";',
|
|
182
|
+
" if(!oldT&&!newT) return null;",
|
|
183
|
+
' return { mode:"lcs", oldText:oldT, newText:newT, caption:("edit "+fp).replace(/\\s+$/,"") };',
|
|
184
|
+
" }",
|
|
185
|
+
' if(n==="write"||n==="write_file"||n==="create_file"){',
|
|
186
|
+
' var c=typeof obj.content==="string"?obj.content:"";',
|
|
187
|
+
" if(!c) return null;",
|
|
188
|
+
' return { mode:"lcs", oldText:"", newText:c, caption:("write "+fp+" (new)").replace(/\\s+/g," ").replace(/\\s+$/,"") };',
|
|
189
|
+
" }",
|
|
190
|
+
' if(n==="patch"){',
|
|
191
|
+
' var pt=typeof obj.patch==="string"?obj.patch:"";',
|
|
192
|
+
' if(!pt.replace(/\\s/g,"")) return null;',
|
|
193
|
+
' return { mode:"unified", patchText:pt, caption: fp ? ("patch "+fp) : "patch" };',
|
|
194
|
+
" }",
|
|
195
|
+
" return null;",
|
|
196
|
+
"}",
|
|
197
|
+
"function computeLineDiff(oldText, newText){",
|
|
198
|
+
' var a=oldText.split("\\n"), b=newText.split("\\n");',
|
|
199
|
+
" if(a.length>DIFF_MAX_LINES||b.length>DIFF_MAX_LINES) return null;",
|
|
200
|
+
" var nn=a.length, mm=b.length, i, j;",
|
|
201
|
+
" var dp=new Array(nn+1); for(i=0;i<=nn;i++){ dp[i]=new Array(mm+1); for(j=0;j<=mm;j++) dp[i][j]=0; }",
|
|
202
|
+
" for(i=nn-1;i>=0;i--){ for(j=mm-1;j>=0;j--){ dp[i][j]= a[i]===b[j] ? dp[i+1][j+1]+1 : Math.max(dp[i+1][j], dp[i][j+1]); } }",
|
|
203
|
+
" var rows=[]; i=0; j=0;",
|
|
204
|
+
' while(i<nn&&j<mm){ if(a[i]===b[j]){ rows.push({kind:"ctx",text:a[i]}); i++; j++; } else if(dp[i+1][j]>=dp[i][j+1]){ rows.push({kind:"del",text:a[i]}); i++; } else { rows.push({kind:"add",text:b[j]}); j++; } }',
|
|
205
|
+
' while(i<nn){ rows.push({kind:"del",text:a[i]}); i++; }',
|
|
206
|
+
' while(j<mm){ rows.push({kind:"add",text:b[j]}); j++; }',
|
|
207
|
+
" return rows;",
|
|
208
|
+
"}",
|
|
209
|
+
"function parseUnifiedDiff(patchText){",
|
|
210
|
+
' var rows=[], lines=patchText.split("\\n"), k, raw;',
|
|
211
|
+
" for(k=0;k<lines.length;k++){ raw=lines[k];",
|
|
212
|
+
' if(raw.indexOf("@@")===0||raw.indexOf("--- ")===0||raw.indexOf("+++ ")===0||raw.indexOf("diff ")===0||raw.indexOf("index ")===0||raw.indexOf("\\\\ ")===0){ rows.push({kind:"meta",text:raw}); }',
|
|
213
|
+
' else if(raw.charAt(0)==="+"){ rows.push({kind:"add",text:raw.slice(1)}); }',
|
|
214
|
+
' else if(raw.charAt(0)==="-"){ rows.push({kind:"del",text:raw.slice(1)}); }',
|
|
215
|
+
' else { rows.push({kind:"ctx",text: raw.charAt(0)===" " ? raw.slice(1) : raw}); }',
|
|
216
|
+
" }",
|
|
217
|
+
' if(rows.length>0 && rows[rows.length-1].kind==="ctx" && rows[rows.length-1].text===""){ rows.pop(); }',
|
|
218
|
+
" return rows;",
|
|
219
|
+
"}",
|
|
220
|
+
"function diffRowsFromToolInput(name, input){",
|
|
221
|
+
" var d=diffFromToolInput(name, input); if(!d) return null;",
|
|
222
|
+
' if(d.mode==="unified") return { caption:d.caption, rows:parseUnifiedDiff(d.patchText) };',
|
|
223
|
+
" return { caption:d.caption, rows:computeLineDiff(d.oldText, d.newText) };",
|
|
224
|
+
"}"
|
|
225
|
+
].join("\n");
|
|
226
|
+
|
|
227
|
+
export { DIFF_LINE_SAFETY_CAP, DIFF_MAX_LINES, TOOL_DIFF_BROWSER_SRC, computeLineDiff, diffFromToolInput, diffRowsFromToolInput, parseUnifiedDiff, parseUnifiedDiffPreview, truncMid };
|
|
228
|
+
//# sourceMappingURL=tool-diff.js.map
|
|
229
|
+
//# sourceMappingURL=tool-diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tool-diff.ts"],"names":["i","j"],"mappings":"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","file":"tool-diff.js","sourcesContent":["// Tool-output diff model — the single source of truth for turning an\n// edit/write/patch tool call into a red/green diff, shared by the WebUI\n// (DiffView) and the HQ dashboard chat-history sidebar.\n//\n// PURE + browser-safe (no node imports). Two consumption modes, mirroring the\n// pattern in ./tool-summary:\n// 1. WebUI/TS: import { diffFromToolInput, computeLineDiff } directly.\n// 2. HQ: it is a served template-literal string that cannot `import`, so it\n// embeds the *_BROWSER_SRC transcriptions and a parity test guarantees the\n// two never drift.\n//\n// Three tool families produce three diff shapes:\n// - edit / str_replace -> { mode:'lcs', oldText, newText } (LCS line diff)\n// - write / create -> { mode:'lcs', oldText:'', newText } (all additions)\n// - patch -> { mode:'unified', patchText } (already a unified\n// diff — parse its hunks directly, do NOT recompute)\n\n/** A single rendered diff line. */\nexport type DiffRowKind = 'add' | 'del' | 'ctx' | 'meta';\nexport interface DiffRow {\n kind: DiffRowKind;\n text: string;\n}\n\n/** Extraction result: enough for a caller to render without re-inspecting input. */\nexport type ToolDiff =\n | { mode: 'lcs'; oldText: string; newText: string; caption: string }\n | { mode: 'unified'; patchText: string; caption: string };\n\n/** Max lines per side before we bail out of the O(n*m) LCS table. */\nexport const DIFF_MAX_LINES = 5000;\n\nfunction asObject(input: unknown): Record<string, unknown> | null {\n if (typeof input === 'string') {\n const s = input.trim();\n if (s.startsWith('{') || s.startsWith('[')) {\n try {\n const parsed = JSON.parse(s);\n if (parsed && typeof parsed === 'object') return parsed as Record<string, unknown>;\n } catch {\n return null;\n }\n }\n return null;\n }\n if (input && typeof input === 'object') return input as Record<string, unknown>;\n return null;\n}\n\n/**\n * Recognise the edit-family tools and pull a renderable diff descriptor out of\n * their input. Returns null when the tool doesn't carry diffable input.\n *\n * @param toolName canonical or aliased tool name.\n * @param input tool input — a parsed object OR a JSON string.\n */\nexport function diffFromToolInput(toolName: string | undefined, input: unknown): ToolDiff | null {\n if (!toolName) return null;\n const obj = asObject(input);\n if (!obj) return null;\n const name = toolName.toLowerCase();\n const filePath = String(obj.file_path ?? obj.path ?? '');\n\n switch (name) {\n case 'edit':\n case 'str_replace':\n case 'edit_file':\n case 'multi_edit': {\n const oldText = typeof obj.old_string === 'string' ? obj.old_string : '';\n const newText = typeof obj.new_string === 'string' ? obj.new_string : '';\n if (!oldText && !newText) return null;\n return { mode: 'lcs', oldText, newText, caption: `edit ${filePath}`.trim() };\n }\n case 'write':\n case 'write_file':\n case 'create_file': {\n const content = typeof obj.content === 'string' ? obj.content : '';\n if (!content) return null;\n // Fresh write: no \"old\" side, everything shows green.\n return { mode: 'lcs', oldText: '', newText: content, caption: `write ${filePath} (new)`.trim() };\n }\n case 'patch': {\n const patchText = typeof obj.patch === 'string' ? obj.patch : '';\n if (!patchText.trim()) return null;\n return { mode: 'unified', patchText, caption: filePath ? `patch ${filePath}` : 'patch' };\n }\n default:\n return null;\n }\n}\n\n/**\n * LCS-based line diff. Returns null when either side exceeds DIFF_MAX_LINES\n * (an O(n*m) memory guard — fine for a normal edit, prohibitive for a huge\n * generated-file rewrite).\n */\nexport function computeLineDiff(oldText: string, newText: string): DiffRow[] | null {\n const a = oldText.split('\\n');\n const b = newText.split('\\n');\n if (a.length > DIFF_MAX_LINES || b.length > DIFF_MAX_LINES) return null;\n const n = a.length;\n const m = b.length;\n // dp[i][j] = LCS length of a[i..] and b[j..]\n const dp: number[][] = Array.from({ length: n + 1 }, () => new Array<number>(m + 1).fill(0));\n for (let i = n - 1; i >= 0; i--) {\n for (let j = m - 1; j >= 0; j--) {\n dp[i]![j] = a[i] === b[j] ? dp[i + 1]![j + 1]! + 1 : Math.max(dp[i + 1]![j]!, dp[i]![j + 1]!);\n }\n }\n const rows: DiffRow[] = [];\n let i = 0;\n let j = 0;\n while (i < n && j < m) {\n if (a[i] === b[j]) {\n rows.push({ kind: 'ctx', text: a[i]! });\n i++;\n j++;\n } else if (dp[i + 1]![j]! >= dp[i]![j + 1]!) {\n rows.push({ kind: 'del', text: a[i]! });\n i++;\n } else {\n rows.push({ kind: 'add', text: b[j]! });\n j++;\n }\n }\n while (i < n) rows.push({ kind: 'del', text: a[i++]! });\n while (j < m) rows.push({ kind: 'add', text: b[j++]! });\n return rows;\n}\n\n/**\n * Parse a unified-diff string into renderable rows. Hunk headers (`@@ ... @@`)\n * and file headers (`--- `, `+++ `, `diff `, `index `) become `meta` rows; body\n * lines map to add/del/ctx by their leading char. `\`\n * is kept as a meta row.\n */\nexport function parseUnifiedDiff(patchText: string): DiffRow[] {\n const rows: DiffRow[] = [];\n const lines = patchText.split('\\n');\n for (const raw of lines) {\n if (\n raw.startsWith('@@') ||\n raw.startsWith('--- ') ||\n raw.startsWith('+++ ') ||\n raw.startsWith('diff ') ||\n raw.startsWith('index ') ||\n raw.startsWith('\\\\ ')\n ) {\n rows.push({ kind: 'meta', text: raw });\n } else if (raw.startsWith('+')) {\n rows.push({ kind: 'add', text: raw.slice(1) });\n } else if (raw.startsWith('-')) {\n rows.push({ kind: 'del', text: raw.slice(1) });\n } else {\n // context line (leading space) or a bare line\n rows.push({ kind: 'ctx', text: raw.startsWith(' ') ? raw.slice(1) : raw });\n }\n }\n // Drop a trailing empty row that a final newline in patchText introduces.\n if (rows.length > 0 && rows[rows.length - 1]!.kind === 'ctx' && rows[rows.length - 1]!.text === '') {\n rows.pop();\n }\n return rows;\n}\n\n/**\n * Convenience: extract + render to rows in one call. Returns null when the tool\n * carries no diffable input, or `{ caption, rows: null }` when the diff is too\n * large to render (LCS guard).\n */\nexport function diffRowsFromToolInput(\n toolName: string | undefined,\n input: unknown,\n): { caption: string; rows: DiffRow[] | null } | null {\n const d = diffFromToolInput(toolName, input);\n if (!d) return null;\n if (d.mode === 'unified') return { caption: d.caption, rows: parseUnifiedDiff(d.patchText) };\n return { caption: d.caption, rows: computeLineDiff(d.oldText, d.newText) };\n}\n\n// ===========================================================================\n// Rich preview model (line-number gutters + maxLines cap + hidden counts).\n//\n// Promoted verbatim from the TUI's code-block.tsx so the terminal can consume\n// this instead of a third local copy. It is a SUPERSET of the flat DiffRow\n// model above: `DiffLineRow` carries per-row old/new line numbers and a `hunk`\n// kind, and `parseUnifiedDiffPreview` returns a `DiffPreview` with add/remove\n// totals plus a maxLines cap that folds the overflow into hidden counts.\n//\n// This is pure and browser-safe; the TUI-only rendering (ink/theme/wrap) stays\n// in code-block.tsx. Kept as separate names from the flat `parseUnifiedDiff`\n// above so WebUI/HQ callers are unaffected.\n// ===========================================================================\n\n/** Rich diff row: like DiffRow but with a dedicated `hunk` kind and gutters. */\nexport type DiffLineKind = 'add' | 'del' | 'hunk' | 'ctx' | 'meta';\nexport interface DiffLineRow {\n kind: DiffLineKind;\n text: string;\n oldLine?: number | undefined;\n newLine?: number | undefined;\n}\n\n/** A parsed unified-diff preview: rows plus visible/hidden tallies. */\nexport interface DiffPreview {\n rows: DiffLineRow[];\n hidden: number;\n added: number;\n removed: number;\n hiddenAdded: number;\n hiddenRemoved: number;\n}\n\n/**\n * Safety cap on a single diff row's stored text — guards against pathological\n * one-line files (minified bundles, huge JSON) flooding a consumer. Real code\n * lines are never truncated at this length.\n */\nexport const DIFF_LINE_SAFETY_CAP = 4000;\n\n/** Truncate the middle-out: keep the head, append an ellipsis, past `max`. */\nexport function truncMid(s: string, max: number): string {\n if (s.length <= max) return s;\n return `${s.slice(0, max - 1)}…`;\n}\n\n/**\n * Parse a unified-diff string into a {@link DiffPreview} with per-row line\n * numbers and add/remove tallies. `maxLines` caps the visible rows; the rest\n * fold into `hidden`/`hiddenAdded`/`hiddenRemoved`. Pass\n * `Number.POSITIVE_INFINITY` to render everything.\n *\n * This is the richer sibling of {@link parseUnifiedDiff}: it keeps a dedicated\n * `hunk` kind (rather than folding hunk headers into `meta`) and tracks old/new\n * line gutters, which a terminal/gutter renderer needs.\n */\nexport function parseUnifiedDiffPreview(\n diff: string,\n maxLines: number,\n lineCap: number = DIFF_LINE_SAFETY_CAP,\n): DiffPreview {\n const all: DiffLineRow[] = [];\n let oldLn = 0;\n let newLn = 0;\n for (const raw of diff.split('\\n')) {\n const line = raw.replace(/\\r$/, '');\n if (line.startsWith('+++') || line.startsWith('---')) continue;\n if (line.startsWith('diff --git') || line.startsWith('index ')) continue;\n if (line.startsWith('@@')) {\n const m = line.match(/^@@\\s+-(\\d+)(?:,\\d+)?\\s+\\+(\\d+)(?:,\\d+)?\\s+@@/);\n if (m) {\n oldLn = Number.parseInt(m[1] ?? '0', 10) || 0;\n newLn = Number.parseInt(m[2] ?? '0', 10) || 0;\n }\n all.push({ kind: 'hunk', text: truncMid(line, 60) });\n continue;\n }\n if (line.startsWith('+')) {\n all.push({ kind: 'add', text: truncMid(line, lineCap), newLine: newLn });\n newLn++;\n continue;\n }\n if (line.startsWith('-')) {\n all.push({ kind: 'del', text: truncMid(line, lineCap), oldLine: oldLn });\n oldLn++;\n continue;\n }\n if (line.startsWith('\\\\ No newline')) {\n all.push({ kind: 'meta', text: line });\n continue;\n }\n if (line.length === 0) continue;\n all.push({ kind: 'ctx', text: truncMid(line, lineCap), oldLine: oldLn, newLine: newLn });\n oldLn++;\n newLn++;\n }\n const added = all.filter((row) => row.kind === 'add').length;\n const removed = all.filter((row) => row.kind === 'del').length;\n if (all.length === 0) {\n return { rows: [], hidden: 0, added: 0, removed: 0, hiddenAdded: 0, hiddenRemoved: 0 };\n }\n if (all.length <= maxLines) {\n return { rows: all, hidden: 0, added, removed, hiddenAdded: 0, hiddenRemoved: 0 };\n }\n const rows = all.slice(0, maxLines);\n const hiddenRows = all.slice(maxLines);\n return {\n rows,\n hidden: hiddenRows.length,\n added,\n removed,\n hiddenAdded: hiddenRows.filter((row) => row.kind === 'add').length,\n hiddenRemoved: hiddenRows.filter((row) => row.kind === 'del').length,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Browser-JS transcriptions for HQ (served template literal, cannot import).\n// Authored with string concatenation only: NO backticks, NO ${...} — the HQ\n// template escapes those. A parity test asserts identical output to the TS\n// functions above. Together these define, on the global scope:\n// diffFromToolInput(name, rawInput) -> {mode,...}|null\n// computeLineDiff(oldText, newText) -> rows|null\n// parseUnifiedDiff(patchText) -> rows\n// diffRowsFromToolInput(name, raw) -> {caption, rows}|null\n// ---------------------------------------------------------------------------\nexport const TOOL_DIFF_BROWSER_SRC: string = [\n 'var DIFF_MAX_LINES = 5000;',\n 'function __diffObj(input){',\n ' if(typeof input===\"string\"){ var s=input.trim(); if(s.charAt(0)===\"{\"||s.charAt(0)===\"[\"){ try{ var p=JSON.parse(s); if(p&&typeof p===\"object\") return p; }catch(_e){} } return null; }',\n ' if(input&&typeof input===\"object\") return input; return null;',\n '}',\n 'function diffFromToolInput(name, input){',\n ' if(!name) return null;',\n ' var obj=__diffObj(input); if(!obj) return null;',\n ' var n=String(name).toLowerCase();',\n ' var fp=String(obj.file_path!=null?obj.file_path:(obj.path!=null?obj.path:\"\"));',\n ' if(n===\"edit\"||n===\"str_replace\"||n===\"edit_file\"||n===\"multi_edit\"){',\n ' var oldT=typeof obj.old_string===\"string\"?obj.old_string:\"\";',\n ' var newT=typeof obj.new_string===\"string\"?obj.new_string:\"\";',\n ' if(!oldT&&!newT) return null;',\n ' return { mode:\"lcs\", oldText:oldT, newText:newT, caption:(\"edit \"+fp).replace(/\\\\s+$/,\"\") };',\n ' }',\n ' if(n===\"write\"||n===\"write_file\"||n===\"create_file\"){',\n ' var c=typeof obj.content===\"string\"?obj.content:\"\";',\n ' if(!c) return null;',\n ' return { mode:\"lcs\", oldText:\"\", newText:c, caption:(\"write \"+fp+\" (new)\").replace(/\\\\s+/g,\" \").replace(/\\\\s+$/,\"\") };',\n ' }',\n ' if(n===\"patch\"){',\n ' var pt=typeof obj.patch===\"string\"?obj.patch:\"\";',\n ' if(!pt.replace(/\\\\s/g,\"\")) return null;',\n ' return { mode:\"unified\", patchText:pt, caption: fp ? (\"patch \"+fp) : \"patch\" };',\n ' }',\n ' return null;',\n '}',\n 'function computeLineDiff(oldText, newText){',\n ' var a=oldText.split(\"\\\\n\"), b=newText.split(\"\\\\n\");',\n ' if(a.length>DIFF_MAX_LINES||b.length>DIFF_MAX_LINES) return null;',\n ' var nn=a.length, mm=b.length, i, j;',\n ' var dp=new Array(nn+1); for(i=0;i<=nn;i++){ dp[i]=new Array(mm+1); for(j=0;j<=mm;j++) dp[i][j]=0; }',\n ' for(i=nn-1;i>=0;i--){ for(j=mm-1;j>=0;j--){ dp[i][j]= a[i]===b[j] ? dp[i+1][j+1]+1 : Math.max(dp[i+1][j], dp[i][j+1]); } }',\n ' var rows=[]; i=0; j=0;',\n ' while(i<nn&&j<mm){ if(a[i]===b[j]){ rows.push({kind:\"ctx\",text:a[i]}); i++; j++; } else if(dp[i+1][j]>=dp[i][j+1]){ rows.push({kind:\"del\",text:a[i]}); i++; } else { rows.push({kind:\"add\",text:b[j]}); j++; } }',\n ' while(i<nn){ rows.push({kind:\"del\",text:a[i]}); i++; }',\n ' while(j<mm){ rows.push({kind:\"add\",text:b[j]}); j++; }',\n ' return rows;',\n '}',\n 'function parseUnifiedDiff(patchText){',\n ' var rows=[], lines=patchText.split(\"\\\\n\"), k, raw;',\n ' for(k=0;k<lines.length;k++){ raw=lines[k];',\n ' if(raw.indexOf(\"@@\")===0||raw.indexOf(\"--- \")===0||raw.indexOf(\"+++ \")===0||raw.indexOf(\"diff \")===0||raw.indexOf(\"index \")===0||raw.indexOf(\"\\\\\\\\ \")===0){ rows.push({kind:\"meta\",text:raw}); }',\n ' else if(raw.charAt(0)===\"+\"){ rows.push({kind:\"add\",text:raw.slice(1)}); }',\n ' else if(raw.charAt(0)===\"-\"){ rows.push({kind:\"del\",text:raw.slice(1)}); }',\n ' else { rows.push({kind:\"ctx\",text: raw.charAt(0)===\" \" ? raw.slice(1) : raw}); }',\n ' }',\n ' if(rows.length>0 && rows[rows.length-1].kind===\"ctx\" && rows[rows.length-1].text===\"\"){ rows.pop(); }',\n ' return rows;',\n '}',\n 'function diffRowsFromToolInput(name, input){',\n ' var d=diffFromToolInput(name, input); if(!d) return null;',\n ' if(d.mode===\"unified\") return { caption:d.caption, rows:parseUnifiedDiff(d.patchText) };',\n ' return { caption:d.caption, rows:computeLineDiff(d.oldText, d.newText) };',\n '}',\n].join('\\n');\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Head-field lookup order for the generic fallback. */
|
|
2
|
+
declare const FALLBACK_HEAD_FIELDS: readonly ["path", "file_path", "pattern", "command", "cmd", "url", "query", "description", "content"];
|
|
3
|
+
/**
|
|
4
|
+
* One-line, tool-aware summary of a tool call's input.
|
|
5
|
+
*
|
|
6
|
+
* @param toolName canonical or aliased tool name (case-insensitive).
|
|
7
|
+
* @param input the tool input — a parsed object OR a JSON string.
|
|
8
|
+
*/
|
|
9
|
+
declare function summarizeToolInput(toolName: string | undefined, input: unknown): string;
|
|
10
|
+
/**
|
|
11
|
+
* Authored-once browser-JS transcription of `summarizeToolInput`, for surfaces
|
|
12
|
+
* that cannot `import` at runtime (the HQ dashboard is a served template-literal
|
|
13
|
+
* string). This is DELIBERATELY written with string concatenation and single
|
|
14
|
+
* backslashes only: the HQ template literal escapes `\` and `` ` ``/`${` before
|
|
15
|
+
* embedding, so this text must contain NO backticks and NO `${` sequences.
|
|
16
|
+
*
|
|
17
|
+
* Defines one global function: `toolInputSummary(name, rawInput)` where
|
|
18
|
+
* rawInput is a JSON string (HQ's on-wire shape) or null.
|
|
19
|
+
*
|
|
20
|
+
* A parity test asserts this produces identical output to the TS function above.
|
|
21
|
+
*/
|
|
22
|
+
declare const SUMMARIZE_TOOL_INPUT_BROWSER_SRC: string;
|
|
23
|
+
|
|
24
|
+
export { FALLBACK_HEAD_FIELDS, SUMMARIZE_TOOL_INPUT_BROWSER_SRC, summarizeToolInput };
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
// src/tool-summary.ts
|
|
2
|
+
var FALLBACK_HEAD_FIELDS = [
|
|
3
|
+
"path",
|
|
4
|
+
"file_path",
|
|
5
|
+
"pattern",
|
|
6
|
+
"command",
|
|
7
|
+
"cmd",
|
|
8
|
+
"url",
|
|
9
|
+
"query",
|
|
10
|
+
"description",
|
|
11
|
+
"content"
|
|
12
|
+
];
|
|
13
|
+
function clip(s, n) {
|
|
14
|
+
return s.length > n ? `${s.slice(0, n - 1)}\u2026` : s;
|
|
15
|
+
}
|
|
16
|
+
function pickPath(obj) {
|
|
17
|
+
const p = obj.file_path ?? obj.path ?? obj.filepath;
|
|
18
|
+
return typeof p === "string" ? p : "";
|
|
19
|
+
}
|
|
20
|
+
function safeJson(v) {
|
|
21
|
+
try {
|
|
22
|
+
return JSON.stringify(v);
|
|
23
|
+
} catch {
|
|
24
|
+
return String(v);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function coerceInput(input) {
|
|
28
|
+
if (typeof input === "string") {
|
|
29
|
+
const s = input.trim();
|
|
30
|
+
if (s.startsWith("{") || s.startsWith("[")) {
|
|
31
|
+
try {
|
|
32
|
+
const parsed = JSON.parse(s);
|
|
33
|
+
if (parsed && typeof parsed === "object") return { obj: parsed, raw: parsed };
|
|
34
|
+
} catch {
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return { obj: null, raw: input };
|
|
38
|
+
}
|
|
39
|
+
if (input && typeof input === "object") return { obj: input, raw: input };
|
|
40
|
+
return { obj: null, raw: input };
|
|
41
|
+
}
|
|
42
|
+
function summarizeToolInput(toolName, input) {
|
|
43
|
+
if (input === null || input === void 0 || input === "") return "";
|
|
44
|
+
const { obj, raw } = coerceInput(input);
|
|
45
|
+
if (!obj) return clip(String(raw), 120);
|
|
46
|
+
const name = (toolName ?? "").toLowerCase();
|
|
47
|
+
if (/^todo(_?write)?$|^todos$/.test(name) || Array.isArray(obj.todos)) {
|
|
48
|
+
const todos = obj.todos ?? [];
|
|
49
|
+
if (Array.isArray(todos)) {
|
|
50
|
+
const done = todos.filter((t) => t?.status === "completed").length;
|
|
51
|
+
const wip = todos.filter((t) => t?.status === "in_progress").length;
|
|
52
|
+
const parts = [`${todos.length} todo${todos.length === 1 ? "" : "s"}`];
|
|
53
|
+
if (done > 0) parts.push(`${done} done`);
|
|
54
|
+
if (wip > 0) parts.push(`${wip} in-progress`);
|
|
55
|
+
return parts.join(" \xB7 ");
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (/batch|parallel/.test(name) || Array.isArray(obj.tool_uses) || Array.isArray(obj.calls)) {
|
|
59
|
+
const list = obj.tool_uses ?? obj.calls ?? obj.batch;
|
|
60
|
+
if (Array.isArray(list)) {
|
|
61
|
+
const subNames = /* @__PURE__ */ new Set();
|
|
62
|
+
for (const item of list) {
|
|
63
|
+
if (item && typeof item === "object" && "name" in item) {
|
|
64
|
+
subNames.add(String(item.name));
|
|
65
|
+
} else if (item && typeof item === "object" && "tool" in item) {
|
|
66
|
+
subNames.add(String(item.tool));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const preview = [...subNames].slice(0, 3).join(", ");
|
|
70
|
+
const more = subNames.size > 3 ? ` +${subNames.size - 3}` : "";
|
|
71
|
+
return `${list.length} sub-tool${list.length === 1 ? "" : "s"}${preview ? ` \xB7 ${preview}${more}` : ""}`;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (/^(edit|str_replace|edit_file|patch)$/.test(name)) {
|
|
75
|
+
const fp = pickPath(obj);
|
|
76
|
+
const oldS = typeof obj.old_string === "string" ? obj.old_string : "";
|
|
77
|
+
const newS = typeof obj.new_string === "string" ? obj.new_string : "";
|
|
78
|
+
const oldLines = oldS ? oldS.split("\n").length : 0;
|
|
79
|
+
const newLines = newS ? newS.split("\n").length : 0;
|
|
80
|
+
return `edit ${fp || "(file)"}${oldLines || newLines ? ` (${oldLines} \u2192 ${newLines} lines)` : ""}`;
|
|
81
|
+
}
|
|
82
|
+
if (/^(write|write_file|create_file|new_file)$/.test(name)) {
|
|
83
|
+
const fp = pickPath(obj);
|
|
84
|
+
const c = typeof obj.content === "string" ? obj.content : "";
|
|
85
|
+
const lines = c ? c.split("\n").length : 0;
|
|
86
|
+
return `write ${fp || "(file)"}${lines ? ` \xB7 ${lines} lines` : ""}`;
|
|
87
|
+
}
|
|
88
|
+
if (/^(bash|shell|sh|exec|run|run_command|run_shell|command)$/.test(name)) {
|
|
89
|
+
const cmd = obj.command ?? obj.cmd ?? obj.script;
|
|
90
|
+
if (typeof cmd === "string") return `$ ${clip(cmd, 110)}`;
|
|
91
|
+
}
|
|
92
|
+
if (/^(fetch|http|web|web_fetch|web_search|webfetch|curl|request)$/.test(name)) {
|
|
93
|
+
const url = obj.url;
|
|
94
|
+
if (typeof url === "string") {
|
|
95
|
+
const method = obj.method ?? "GET";
|
|
96
|
+
return `${method.toUpperCase()} ${clip(url, 100)}`;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (/^(grep|search|ripgrep|rg)$/.test(name)) {
|
|
100
|
+
const pattern = obj.pattern;
|
|
101
|
+
const scope = obj.path ?? obj.glob ?? obj.type;
|
|
102
|
+
if (typeof pattern === "string") {
|
|
103
|
+
return scope ? `grep ${clip(pattern, 60)} in ${scope}` : `grep ${clip(pattern, 100)}`;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (/^(glob|find)$/.test(name)) {
|
|
107
|
+
const p = obj.pattern ?? obj.glob;
|
|
108
|
+
if (typeof p === "string") return `glob ${clip(p, 80)}`;
|
|
109
|
+
}
|
|
110
|
+
if (/^(read|read_file|cat|view)$/.test(name)) {
|
|
111
|
+
const fp = pickPath(obj);
|
|
112
|
+
const offset = obj.offset;
|
|
113
|
+
const limit = obj.limit;
|
|
114
|
+
if (fp && (typeof offset === "number" || typeof limit === "number")) {
|
|
115
|
+
const start = offset ?? 0;
|
|
116
|
+
const end = typeof limit === "number" ? start + limit : "";
|
|
117
|
+
return `read ${fp} (${start}\u2026${end})`;
|
|
118
|
+
}
|
|
119
|
+
if (fp) return `read ${fp}`;
|
|
120
|
+
}
|
|
121
|
+
for (const k of FALLBACK_HEAD_FIELDS) {
|
|
122
|
+
const v = obj[k];
|
|
123
|
+
if (typeof v === "string" && v.length > 0) {
|
|
124
|
+
return `${k}: ${clip(v, 100)}`;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return clip(safeJson(raw), 120);
|
|
128
|
+
}
|
|
129
|
+
var SUMMARIZE_TOOL_INPUT_BROWSER_SRC = [
|
|
130
|
+
'function __clip(s,n){ s=String(s==null?"":s); return s.length>n ? s.slice(0,n-1)+"\\u2026" : s; }',
|
|
131
|
+
"function toolInputSummary(name, rawInput){",
|
|
132
|
+
' if(rawInput==null || rawInput==="") return "";',
|
|
133
|
+
" var obj=null, raw=rawInput;",
|
|
134
|
+
' if(typeof rawInput==="string"){',
|
|
135
|
+
" var s=rawInput.trim();",
|
|
136
|
+
' if(s.charAt(0)==="{" || s.charAt(0)==="["){ try{ var pj=JSON.parse(s); if(pj && typeof pj==="object"){ obj=pj; raw=pj; } }catch(_e){} }',
|
|
137
|
+
' } else if(rawInput && typeof rawInput==="object"){ obj=rawInput; raw=rawInput; }',
|
|
138
|
+
" if(!obj) return __clip(String(raw),120);",
|
|
139
|
+
' var n=String(name==null?"":name).toLowerCase();',
|
|
140
|
+
" if(/^todo(_?write)?$|^todos$/.test(n) || Array.isArray(obj.todos)){",
|
|
141
|
+
" var todos=obj.todos||[];",
|
|
142
|
+
" if(Array.isArray(todos)){",
|
|
143
|
+
" var done=0, wip=0, ti;",
|
|
144
|
+
' for(ti=0; ti<todos.length; ti++){ var st=todos[ti]&&todos[ti].status; if(st==="completed") done++; else if(st==="in_progress") wip++; }',
|
|
145
|
+
' var tp=[todos.length+" todo"+(todos.length===1?"":"s")];',
|
|
146
|
+
' if(done>0) tp.push(done+" done"); if(wip>0) tp.push(wip+" in-progress");',
|
|
147
|
+
' return tp.join(" \\u00b7 ");',
|
|
148
|
+
" }",
|
|
149
|
+
" }",
|
|
150
|
+
" if(/batch|parallel/.test(n) || Array.isArray(obj.tool_uses) || Array.isArray(obj.calls)){",
|
|
151
|
+
" var list=obj.tool_uses||obj.calls||obj.batch;",
|
|
152
|
+
" if(Array.isArray(list)){",
|
|
153
|
+
" var names={}, ord=[], li, it, nm;",
|
|
154
|
+
' for(li=0; li<list.length; li++){ it=list[li]; if(it && typeof it==="object"){ nm=("name" in it)?it.name:(("tool" in it)?it.tool:null); if(nm!=null){ nm=String(nm); if(!names[nm]){ names[nm]=1; ord.push(nm); } } } }',
|
|
155
|
+
' var preview=ord.slice(0,3).join(", ");',
|
|
156
|
+
' var more=ord.length>3 ? " +"+(ord.length-3) : "";',
|
|
157
|
+
' return list.length+" sub-tool"+(list.length===1?"":"s")+(preview?(" \\u00b7 "+preview+more):"");',
|
|
158
|
+
" }",
|
|
159
|
+
" }",
|
|
160
|
+
" var fp;",
|
|
161
|
+
" if(/^(edit|str_replace|edit_file|patch)$/.test(n)){",
|
|
162
|
+
" fp=(obj.file_path!=null?obj.file_path:(obj.path!=null?obj.path:obj.filepath));",
|
|
163
|
+
' var oldS=typeof obj.old_string==="string"?obj.old_string:"";',
|
|
164
|
+
' var newS=typeof obj.new_string==="string"?obj.new_string:"";',
|
|
165
|
+
' var ol=oldS?oldS.split("\\n").length:0, nl=newS?newS.split("\\n").length:0;',
|
|
166
|
+
' var efp=typeof fp==="string"?fp:"";',
|
|
167
|
+
' return "edit "+(efp||"(file)")+((ol||nl)?(" ("+ol+" \\u2192 "+nl+" lines)"):"");',
|
|
168
|
+
" }",
|
|
169
|
+
" if(/^(write|write_file|create_file|new_file)$/.test(n)){",
|
|
170
|
+
" fp=(obj.file_path!=null?obj.file_path:(obj.path!=null?obj.path:obj.filepath));",
|
|
171
|
+
' var wc=typeof obj.content==="string"?obj.content:"";',
|
|
172
|
+
' var wl=wc?wc.split("\\n").length:0;',
|
|
173
|
+
' var wfp=typeof fp==="string"?fp:"";',
|
|
174
|
+
' return "write "+(wfp||"(file)")+(wl?(" \\u00b7 "+wl+" lines"):"");',
|
|
175
|
+
" }",
|
|
176
|
+
" if(/^(bash|shell|sh|exec|run|run_command|run_shell|command)$/.test(n)){",
|
|
177
|
+
" var cmd=(obj.command!=null?obj.command:(obj.cmd!=null?obj.cmd:obj.script));",
|
|
178
|
+
' if(typeof cmd==="string") return "$ "+__clip(cmd,110);',
|
|
179
|
+
" }",
|
|
180
|
+
" if(/^(fetch|http|web|web_fetch|web_search|webfetch|curl|request)$/.test(n)){",
|
|
181
|
+
' if(typeof obj.url==="string"){ var mth=(typeof obj.method==="string"?obj.method:"GET"); return mth.toUpperCase()+" "+__clip(obj.url,100); }',
|
|
182
|
+
" }",
|
|
183
|
+
" if(/^(grep|search|ripgrep|rg)$/.test(n)){",
|
|
184
|
+
" var pat=obj.pattern, scope=(obj.path!=null?obj.path:(obj.glob!=null?obj.glob:obj.type));",
|
|
185
|
+
' if(typeof pat==="string"){ return scope ? ("grep "+__clip(pat,60)+" in "+scope) : ("grep "+__clip(pat,100)); }',
|
|
186
|
+
" }",
|
|
187
|
+
" if(/^(glob|find)$/.test(n)){",
|
|
188
|
+
" var gp=(obj.pattern!=null?obj.pattern:obj.glob);",
|
|
189
|
+
' if(typeof gp==="string") return "glob "+__clip(gp,80);',
|
|
190
|
+
" }",
|
|
191
|
+
" if(/^(read|read_file|cat|view)$/.test(n)){",
|
|
192
|
+
" fp=(obj.file_path!=null?obj.file_path:(obj.path!=null?obj.path:obj.filepath));",
|
|
193
|
+
' if(typeof fp==="string" && fp){',
|
|
194
|
+
" var off=obj.offset, lim=obj.limit;",
|
|
195
|
+
' if(typeof off==="number" || typeof lim==="number"){ var start=(typeof off==="number"?off:0); var end=(typeof lim==="number"?(start+lim):""); return "read "+fp+" ("+start+"\\u2026"+end+")"; }',
|
|
196
|
+
' return "read "+fp;',
|
|
197
|
+
" }",
|
|
198
|
+
" }",
|
|
199
|
+
' var HEAD=["path","file_path","pattern","command","cmd","url","query","description","content"], hi;',
|
|
200
|
+
' for(hi=0; hi<HEAD.length; hi++){ var hv=obj[HEAD[hi]]; if(typeof hv==="string" && hv.length>0){ return HEAD[hi]+": "+__clip(hv,100); } }',
|
|
201
|
+
" var jsonStr; try{ jsonStr=JSON.stringify(raw); }catch(_e2){ jsonStr=String(raw); }",
|
|
202
|
+
" return __clip(jsonStr,120);",
|
|
203
|
+
"}"
|
|
204
|
+
].join("\n");
|
|
205
|
+
|
|
206
|
+
export { FALLBACK_HEAD_FIELDS, SUMMARIZE_TOOL_INPUT_BROWSER_SRC, summarizeToolInput };
|
|
207
|
+
//# sourceMappingURL=tool-summary.js.map
|
|
208
|
+
//# sourceMappingURL=tool-summary.js.map
|