@jaggerxtrm/pi-extensions 0.8.0 → 0.8.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/extensions/xtrm-ui/format.ts +22 -2
- package/extensions/xtrm-ui/index.ts +29 -19
- package/package.json +1 -1
|
@@ -260,8 +260,8 @@ export function formatLineLabel(count: number, noun: string): string {
|
|
|
260
260
|
|
|
261
261
|
export const TOOL_ROW_MARKER = "›";
|
|
262
262
|
|
|
263
|
-
const TOOL_SUMMARY_SUBJECT_MAX =
|
|
264
|
-
const TOOL_SUMMARY_META_MAX =
|
|
263
|
+
const TOOL_SUMMARY_SUBJECT_MAX = 80;
|
|
264
|
+
const TOOL_SUMMARY_META_MAX = 64;
|
|
265
265
|
|
|
266
266
|
export function renderToolSummary(
|
|
267
267
|
theme: { fg(color: string, text: string): string; bold(text: string): string },
|
|
@@ -287,3 +287,23 @@ export function joinMeta(parts: Array<string | undefined | false>): string | und
|
|
|
287
287
|
const filtered = parts.filter((part): part is string => typeof part === "string" && part.length > 0);
|
|
288
288
|
return filtered.length > 0 ? filtered.join(" · ") : undefined;
|
|
289
289
|
}
|
|
290
|
+
|
|
291
|
+
export function joinCompactMeta(parts: Array<string | undefined | false>): string | undefined {
|
|
292
|
+
const filtered = parts.filter((part): part is string => typeof part === "string" && part.length > 0);
|
|
293
|
+
return filtered.length > 0 ? filtered.join(":") : undefined;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export function formatPayloadSize(text: string | undefined): string | undefined {
|
|
297
|
+
if (!text) return undefined;
|
|
298
|
+
const bytes = new TextEncoder().encode(text).length;
|
|
299
|
+
if (bytes <= 0) return undefined;
|
|
300
|
+
if (bytes < 1024) return `${bytes}B`;
|
|
301
|
+
|
|
302
|
+
const kib = bytes / 1024;
|
|
303
|
+
if (kib < 1024) {
|
|
304
|
+
return `${kib < 10 ? kib.toFixed(1) : Math.round(kib)}KB`;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const mib = kib / 1024;
|
|
308
|
+
return `${mib < 10 ? mib.toFixed(1) : Math.round(mib)}MB`;
|
|
309
|
+
}
|
|
@@ -42,6 +42,8 @@ import {
|
|
|
42
42
|
diffStats,
|
|
43
43
|
formatDuration,
|
|
44
44
|
formatLineLabel,
|
|
45
|
+
formatPayloadSize,
|
|
46
|
+
joinCompactMeta,
|
|
45
47
|
joinMeta,
|
|
46
48
|
lineCount,
|
|
47
49
|
previewLines,
|
|
@@ -1129,9 +1131,10 @@ function summarizeSerenaToolResult(
|
|
|
1129
1131
|
): string {
|
|
1130
1132
|
const payload = parseJson(text);
|
|
1131
1133
|
const duration = formatDuration(durationMs);
|
|
1134
|
+
const payloadSize = formatPayloadSize(text);
|
|
1132
1135
|
const subject = summarizeSerenaSubject(toolName, input);
|
|
1133
1136
|
const meta = (...parts: Array<string | undefined>) => {
|
|
1134
|
-
const joined =
|
|
1137
|
+
const joined = joinCompactMeta([duration, payloadSize, ...parts]);
|
|
1135
1138
|
return joined ? ` · ${joined}` : "";
|
|
1136
1139
|
};
|
|
1137
1140
|
|
|
@@ -1141,28 +1144,28 @@ function summarizeSerenaToolResult(
|
|
|
1141
1144
|
case "jet_brains_find_symbol":
|
|
1142
1145
|
case "jet_brains_find_referencing_symbols": {
|
|
1143
1146
|
const count = countJsonItems(payload) ?? (text.match(/"name_path"\s*:/g)?.length ?? 0);
|
|
1144
|
-
return `${TOOL_ROW_MARKER} serena ${toolName} ${subject ?? "symbol"}${meta(formatLineLabel(count, "result")
|
|
1147
|
+
return `${TOOL_ROW_MARKER} serena ${toolName} ${subject ?? "symbol"}${meta(formatLineLabel(count, "result"))}`;
|
|
1145
1148
|
}
|
|
1146
1149
|
case "get_symbols_overview":
|
|
1147
1150
|
case "jet_brains_get_symbols_overview":
|
|
1148
1151
|
case "jet_brains_type_hierarchy": {
|
|
1149
1152
|
const count = Math.max(countOverviewSymbols(payload), text.match(/"name_path"\s*:/g)?.length ?? 0);
|
|
1150
|
-
return `${TOOL_ROW_MARKER} serena ${toolName} ${subject ?? "file"}${meta(formatLineLabel(count, "symbol")
|
|
1153
|
+
return `${TOOL_ROW_MARKER} serena ${toolName} ${subject ?? "file"}${meta(formatLineLabel(count, "symbol"))}`;
|
|
1151
1154
|
}
|
|
1152
1155
|
case "search_for_pattern": {
|
|
1153
1156
|
const count = countSearchMatches(payload) ?? (text.match(/^\s*>\s*\d+:/gm)?.length ?? 0);
|
|
1154
|
-
return `${TOOL_ROW_MARKER} serena search ${subject ?? "pattern"}${meta(formatLineLabel(count, "match")
|
|
1157
|
+
return `${TOOL_ROW_MARKER} serena search ${subject ?? "pattern"}${meta(formatLineLabel(count, "match"))}`;
|
|
1155
1158
|
}
|
|
1156
1159
|
case "read_file": {
|
|
1157
|
-
return `${TOOL_ROW_MARKER} serena read ${subject ?? "file"}${meta(formatLineLabel(countLines(text), "line")
|
|
1160
|
+
return `${TOOL_ROW_MARKER} serena read ${subject ?? "file"}${meta(formatLineLabel(countLines(text), "line"))}`;
|
|
1158
1161
|
}
|
|
1159
1162
|
case "list_dir": {
|
|
1160
1163
|
const count = countJsonItems(payload) ?? countLines(text);
|
|
1161
|
-
return `${TOOL_ROW_MARKER} serena list_dir ${subject ?? "."}${meta(formatLineLabel(count, "entry")
|
|
1164
|
+
return `${TOOL_ROW_MARKER} serena list_dir ${subject ?? "."}${meta(formatLineLabel(count, "entry"))}`;
|
|
1162
1165
|
}
|
|
1163
1166
|
case "find_file": {
|
|
1164
1167
|
const count = countJsonItems(payload) ?? countLines(text);
|
|
1165
|
-
return `${TOOL_ROW_MARKER} serena find_file ${String(input.file_mask ?? "")}${meta(formatLineLabel(count, "match")
|
|
1168
|
+
return `${TOOL_ROW_MARKER} serena find_file ${String(input.file_mask ?? "")}${meta(formatLineLabel(count, "match"))}`;
|
|
1166
1169
|
}
|
|
1167
1170
|
case "replace_symbol_body":
|
|
1168
1171
|
case "insert_after_symbol":
|
|
@@ -1183,14 +1186,14 @@ function summarizeSerenaToolResult(
|
|
|
1183
1186
|
case "restart_language_server":
|
|
1184
1187
|
case "onboarding":
|
|
1185
1188
|
case "serena_mcp_reset":
|
|
1186
|
-
return `${TOOL_ROW_MARKER} serena ${toolName}${subject ? ` ${subject}` : ""}${meta(
|
|
1189
|
+
return `${TOOL_ROW_MARKER} serena ${toolName}${subject ? ` ${subject}` : ""}${meta()}`;
|
|
1187
1190
|
case "execute_shell_command": {
|
|
1188
1191
|
const count = countLines(text);
|
|
1189
|
-
return `${TOOL_ROW_MARKER} serena shell ${subject ?? "command"}${meta(formatLineLabel(count, "line")
|
|
1192
|
+
return `${TOOL_ROW_MARKER} serena shell ${subject ?? "command"}${meta(formatLineLabel(count, "line"))}`;
|
|
1190
1193
|
}
|
|
1191
1194
|
default: {
|
|
1192
1195
|
const count = countJsonItems(payload) ?? countLines(text);
|
|
1193
|
-
return `${TOOL_ROW_MARKER} serena ${toolName}${subject ? ` ${subject}` : ""}${meta(formatLineLabel(count, "item")
|
|
1196
|
+
return `${TOOL_ROW_MARKER} serena ${toolName}${subject ? ` ${subject}` : ""}${meta(formatLineLabel(count, "item"))}`;
|
|
1194
1197
|
}
|
|
1195
1198
|
}
|
|
1196
1199
|
}
|
|
@@ -1253,10 +1256,11 @@ function summarizeGenericToolResult(
|
|
|
1253
1256
|
): string {
|
|
1254
1257
|
const payload = parseJson(text);
|
|
1255
1258
|
const duration = formatDuration(durationMs);
|
|
1259
|
+
const payloadSize = formatPayloadSize(text);
|
|
1256
1260
|
const subject = summarizeToolSubject(toolName, input) ?? summarizeSerenaSubject(toolName, input);
|
|
1257
1261
|
const count = countJsonItems(payload) ?? countLines(text);
|
|
1258
1262
|
const label = formatLineLabel(count, "line");
|
|
1259
|
-
const joined =
|
|
1263
|
+
const joined = joinCompactMeta([duration, payloadSize, label]);
|
|
1260
1264
|
const normalized = normalizeToolLabel(toolName);
|
|
1261
1265
|
return `${TOOL_ROW_MARKER} ${normalized}${subject ? ` ${subject}` : ""}${joined ? ` · ${joined}` : ""}`;
|
|
1262
1266
|
}
|
|
@@ -1274,8 +1278,8 @@ function summarizeStructuredReturnToolResult(
|
|
|
1274
1278
|
const summary = resultLines.find((line) => !line.startsWith("cwd:"));
|
|
1275
1279
|
const parser = typeof record?.parser === "string" ? record.parser : undefined;
|
|
1276
1280
|
const exitCode = typeof record?.exitCode === "number" ? `exit ${record.exitCode}` : undefined;
|
|
1277
|
-
const
|
|
1278
|
-
const meta = joinMeta([summary ? shortenCommand(summary, 72) : undefined, parser, exitCode,
|
|
1281
|
+
const resultMeta = joinCompactMeta([formatDuration(durationMs), formatPayloadSize(text)]);
|
|
1282
|
+
const meta = joinMeta([summary ? shortenCommand(summary, 72) : undefined, parser, exitCode, resultMeta]);
|
|
1279
1283
|
return `${TOOL_ROW_MARKER} structured_return ${command}${meta ? ` · ${meta}` : ""}`;
|
|
1280
1284
|
}
|
|
1281
1285
|
|
|
@@ -1288,8 +1292,9 @@ function summarizeProcessToolResult(
|
|
|
1288
1292
|
const record = asRecord(details);
|
|
1289
1293
|
const action = String(record?.action ?? input.action ?? "action");
|
|
1290
1294
|
const duration = formatDuration(durationMs);
|
|
1295
|
+
const payloadSize = formatPayloadSize(text);
|
|
1291
1296
|
const meta = (...parts: Array<string | undefined>) => {
|
|
1292
|
-
const joined =
|
|
1297
|
+
const joined = joinCompactMeta([duration, payloadSize, ...parts]);
|
|
1293
1298
|
return joined ? ` · ${joined}` : "";
|
|
1294
1299
|
};
|
|
1295
1300
|
|
|
@@ -1325,7 +1330,7 @@ function summarizeProcessToolResult(
|
|
|
1325
1330
|
}
|
|
1326
1331
|
|
|
1327
1332
|
const message = typeof record?.message === "string" ? record.message : text.split("\n")[0];
|
|
1328
|
-
return `${TOOL_ROW_MARKER} process ${action}${message ? ` · ${shortenCommand(message, 38)}` : ""}${
|
|
1333
|
+
return `${TOOL_ROW_MARKER} process ${action}${message ? ` · ${shortenCommand(message, 38)}` : ""}${meta()}`;
|
|
1329
1334
|
}
|
|
1330
1335
|
|
|
1331
1336
|
function summarizeExternalToolResult(
|
|
@@ -1451,17 +1456,22 @@ function registerXtrmUiTools(pi: ExtensionAPI, getPrefs: () => XtrmUiPrefs): voi
|
|
|
1451
1456
|
renderResult(result, { expanded, isPartial }, theme) {
|
|
1452
1457
|
const details = (result.details ?? {}) as DetailsWithXtrmMeta<BashToolDetails, Record<string, unknown>>;
|
|
1453
1458
|
const meta = getXtrmMeta<BashToolDetails, Record<string, unknown>>(details);
|
|
1454
|
-
const command = shortenCommand(String(meta?.args.command ?? ""),
|
|
1459
|
+
const command = shortenCommand(String(meta?.args.command ?? ""), 80);
|
|
1455
1460
|
if (isPartial) {
|
|
1456
|
-
return toolRowText(theme, `${theme.fg("accent", TOOL_ROW_MARKER)} ${theme.fg("toolTitle", "
|
|
1461
|
+
return toolRowText(theme, `${theme.fg("accent", TOOL_ROW_MARKER)} ${theme.fg("toolTitle", "bash:")}${theme.fg("accent", command)}`);
|
|
1457
1462
|
}
|
|
1458
1463
|
const output = getTextContent(result as any);
|
|
1459
1464
|
const outputLines = cleanOutputLines(output);
|
|
1460
1465
|
const exitMatch = output.match(/exit code:\s*(-?\d+)/i);
|
|
1461
1466
|
const exitCode = exitMatch ? Number.parseInt(exitMatch[1] ?? "0", 10) : 0;
|
|
1462
1467
|
const bullet = exitCode === 0 ? theme.fg("success", TOOL_ROW_MARKER) : theme.fg("error", TOOL_ROW_MARKER);
|
|
1463
|
-
const summary =
|
|
1464
|
-
|
|
1468
|
+
const summary = joinCompactMeta([
|
|
1469
|
+
formatDuration(meta?.durationMs),
|
|
1470
|
+
formatPayloadSize(output),
|
|
1471
|
+
formatLineLabel(outputLines.length, "line"),
|
|
1472
|
+
details.truncation?.truncated ? "truncated" : undefined,
|
|
1473
|
+
]);
|
|
1474
|
+
let text = `${bullet} ${theme.fg("toolTitle", "bash:")}${theme.fg("accent", command)}`;
|
|
1465
1475
|
if (summary) text += theme.fg("dim", ` · ${summary}`);
|
|
1466
1476
|
if (expanded && outputLines.length > 0) text += `\n${renderVerticalPreview(theme, outputLines, 10)}`;
|
|
1467
1477
|
return toolRowText(theme, text);
|