@pi-kaush/pi-tool-call-markers 0.3.0 → 0.3.2
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/CHANGELOG.md +14 -0
- package/README.md +4 -4
- package/package.json +1 -1
- package/src/index.ts +153 -44
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
- Restore Pi 0.85's click-to-expand under the custom collapsed rows. Pi routes
|
|
6
|
+
mouse clicks by per-child rendered line heights, and the grouping render
|
|
7
|
+
bypassed the native render that refreshes that cache, so clicks on anything
|
|
8
|
+
drawn after the first tool call landed nowhere (or one line off after a
|
|
9
|
+
resize). The grouped render now publishes the drawn accounting, and a
|
|
10
|
+
collapsed tool row toggles expansion on left-click like Pi's native result
|
|
11
|
+
region.
|
|
12
|
+
|
|
13
|
+
- Restyle subagent rows: the subagent marker is now `↪` (was `&`), and single
|
|
14
|
+
calls drop the `subagent` tool label — `↪ 🤖 [coder][c3po] Implement the…` —
|
|
15
|
+
with chain/parallel step lines reordered to emoji, profile badge, name badge
|
|
16
|
+
(`1. 🐝 [workhorse][bee] …`). Single-call headings are now scraped too, so
|
|
17
|
+
agent emojis appear on single rows, not just chain/parallel steps.
|
|
18
|
+
|
|
5
19
|
- Color collapsed rows (tool calls, `+ Thought`, subagents) from the
|
|
6
20
|
theme's `syntaxComment` token — which ships with every theme — instead of
|
|
7
21
|
the louder muted/toolTitle/toolOutput split. The bolded tool name and the
|
package/README.md
CHANGED
|
@@ -34,19 +34,19 @@ Collapsed tool rows use semantic theme colors with no gear, background fill, box
|
|
|
34
34
|
|
|
35
35
|
## Subagent plans
|
|
36
36
|
|
|
37
|
-
A recognized `subagent` call renders as an unboxed plan in the shared tool aesthetic, marked with
|
|
37
|
+
A recognized `subagent` call renders as an unboxed plan in the shared tool aesthetic, marked with `↪` instead of the ordinary `%` tool marker:
|
|
38
38
|
|
|
39
39
|
```text
|
|
40
|
-
|
|
40
|
+
↪ subagent chain (3 steps) [repo-review]
|
|
41
41
|
1. 🐝 bee [workhorse] Challenge the compatibility conclusion…
|
|
42
42
|
2. 🐝 bee …
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
Single calls stay on one
|
|
45
|
+
Single calls stay on one `↪ [<emoji>] [<profile>][<agent>] <task preview>` row — no tool label; the `↪` marker identifies it. Chain calls get a heading with the kind, count, and scope followed by numbered steps (parallel tasks list without numbers), with each step ordered emoji, profile badge, name badge. Agent display names (emoji + name) are scraped from the native plan component — including the single-call heading — with an args fallback, and render in `accent`; everything else stays muted, and failed subagents go full red. Subagents never join ordinary tool groups.
|
|
46
46
|
|
|
47
47
|
While a subagent runs, the plan headline's tail shows live progress from the streamed result details — `→ 1 turn · provider/model` in the warning tone — and a settled call keeps the same `→ N turns · provider/model` summary in muted (turns aggregate across tasks; the model shows only when every task used the same one).
|
|
48
48
|
|
|
49
|
-
Malformed, ambiguous, future, or too-narrow shapes fall back to the generic
|
|
49
|
+
Malformed, ambiguous, future, or too-narrow shapes fall back to the generic `↪ subagent …` collapsed row rather than dropping information, and `Ctrl+O` still exposes the native subagent renderer.
|
|
50
50
|
|
|
51
51
|
## Edit diffs
|
|
52
52
|
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -20,7 +20,7 @@ import { fgCollapsed } from "./muted.ts";
|
|
|
20
20
|
|
|
21
21
|
const OUTER_INSET = 2;
|
|
22
22
|
const GROUP_MARKER = "%";
|
|
23
|
-
const SUBAGENT_MARKER = "
|
|
23
|
+
const SUBAGENT_MARKER = "↪";
|
|
24
24
|
const PRESENTATION_PATCHED = Symbol.for("kg.pi.toolPresentation.v3");
|
|
25
25
|
const LEGACY_PRESENTATION_PATCHED = Symbol.for("kg.pi.toolPresentation.v2");
|
|
26
26
|
const GROUPING_PATCHED = Symbol.for("kg.pi.toolGrouping.v1");
|
|
@@ -64,6 +64,8 @@ type ToolExecutionRow = {
|
|
|
64
64
|
imageSpacers?: unknown[];
|
|
65
65
|
getRenderShell?(): "default" | "self";
|
|
66
66
|
getTextOutput?(): string;
|
|
67
|
+
setExpanded?(expanded: boolean): void;
|
|
68
|
+
handleMouse?(event: unknown): unknown;
|
|
67
69
|
};
|
|
68
70
|
|
|
69
71
|
type PresentationPatchState = {
|
|
@@ -76,8 +78,10 @@ type PresentationPatchState = {
|
|
|
76
78
|
rowGroups: WeakMap<ToolExecutionRow, ToolExecutionRow[]>;
|
|
77
79
|
originalRender: (width: number) => string[];
|
|
78
80
|
originalUpdateDisplay: () => void;
|
|
81
|
+
originalHandleMouse?: (this: ToolExecutionRow, event: unknown) => unknown;
|
|
79
82
|
patchedRender?: (width: number) => string[];
|
|
80
83
|
patchedUpdateDisplay?: () => void;
|
|
84
|
+
patchedHandleMouse?: (this: ToolExecutionRow, event: unknown) => unknown;
|
|
81
85
|
};
|
|
82
86
|
|
|
83
87
|
type GroupingPatchState = {
|
|
@@ -90,6 +94,10 @@ type GroupingPatchState = {
|
|
|
90
94
|
|
|
91
95
|
type GroupRenderCache = {
|
|
92
96
|
lines: string[];
|
|
97
|
+
// Per-member click-routing accounting for the group block: the first
|
|
98
|
+
// member absorbs the leading blank and the tool-name header, later
|
|
99
|
+
// members carry their own line (plus edit diffs).
|
|
100
|
+
heights: Array<{ component: ToolExecutionRow; height: number }>;
|
|
93
101
|
members: ToolExecutionRow[];
|
|
94
102
|
memberVersions: number[];
|
|
95
103
|
themeSample: string;
|
|
@@ -1028,6 +1036,19 @@ function parseStepContent(content: string): {
|
|
|
1028
1036
|
};
|
|
1029
1037
|
}
|
|
1030
1038
|
|
|
1039
|
+
// Splits a scraped "emoji name" display into its emoji prefix and bare name;
|
|
1040
|
+
// plain names pass through with no emoji.
|
|
1041
|
+
function splitEmojiName(
|
|
1042
|
+
displayName: string,
|
|
1043
|
+
bareName: string,
|
|
1044
|
+
): { emoji: string; name: string } {
|
|
1045
|
+
const tokens = displayName.trim().split(/\s+/).filter(Boolean);
|
|
1046
|
+
if (tokens.length > 1 && tokens[tokens.length - 1] === bareName) {
|
|
1047
|
+
return { emoji: tokens.slice(0, -1).join(" "), name: bareName };
|
|
1048
|
+
}
|
|
1049
|
+
return { emoji: "", name: bareName };
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1031
1052
|
// Agent display names (emoji + name) come from the subagent extension's own
|
|
1032
1053
|
// call component when available; args only carry the bare agent name.
|
|
1033
1054
|
function scrapeSubagentDisplayNames(
|
|
@@ -1042,10 +1063,16 @@ function scrapeSubagentDisplayNames(
|
|
|
1042
1063
|
try {
|
|
1043
1064
|
for (const raw of component.render(120)) {
|
|
1044
1065
|
const line = sanitizeInline(stripAnsi(raw)).trim();
|
|
1045
|
-
if (!line
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1066
|
+
if (!line) continue;
|
|
1067
|
+
// Single calls carry the agent name on their "subagent <name>" heading
|
|
1068
|
+
// line; stripping the heading word (and step numbers) lets both shapes
|
|
1069
|
+
// flow through the same parse. Heading remainders without an emoji
|
|
1070
|
+
// (e.g. "chain (2 steps)") degrade to displayName === bareName and are
|
|
1071
|
+
// skipped by the guard below.
|
|
1072
|
+
const content = line
|
|
1073
|
+
.replace(/^subagent\b\s*/, "")
|
|
1074
|
+
.replace(/^\d+\.\s*/, "");
|
|
1075
|
+
const { displayName, bareName } = parseStepContent(content);
|
|
1049
1076
|
if (displayName && bareName && displayName !== bareName) {
|
|
1050
1077
|
names.set(bareName, displayName);
|
|
1051
1078
|
}
|
|
@@ -1091,10 +1118,11 @@ function subagentProgressText(row: ToolExecutionRow): string | undefined {
|
|
|
1091
1118
|
return parts.length > 0 ? parts.join(" · ") : undefined;
|
|
1092
1119
|
}
|
|
1093
1120
|
|
|
1094
|
-
// Subagents render as an ordinary unboxed tool block: a
|
|
1121
|
+
// Subagents render as an ordinary unboxed tool block: a `↪` heading with the
|
|
1095
1122
|
// plan kind/count/scope, then the numbered chain steps or parallel tasks with
|
|
1096
|
-
// agent
|
|
1097
|
-
//
|
|
1123
|
+
// agent identities (emoji, profile badge, name badge) in accent. Single calls
|
|
1124
|
+
// collapse to one row: `↪ <emoji> [<profile>][<name>] <task preview>`. Everything
|
|
1125
|
+
// else stays muted (or error on failure), matching the shared tool-row aesthetic.
|
|
1098
1126
|
function renderSubagentPlan(
|
|
1099
1127
|
row: ToolExecutionRow,
|
|
1100
1128
|
width: number,
|
|
@@ -1110,19 +1138,21 @@ function renderSubagentPlan(
|
|
|
1110
1138
|
const displayNames = scrapeSubagentDisplayNames(row);
|
|
1111
1139
|
// Agent/profile/task values are model-supplied; sanitize them like every
|
|
1112
1140
|
// other collapsed-row text so control bytes cannot reach the terminal.
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
);
|
|
1141
|
+
// Identity order: emoji, then the profile and agent-name badges.
|
|
1142
|
+
const identityOf = (step: SubagentStep) => {
|
|
1143
|
+
const displayName =
|
|
1144
|
+
displayNames.get(step.agent) ?? sanitizeInline(step.agent);
|
|
1145
|
+
const { emoji, name } = splitEmojiName(displayName, step.agent);
|
|
1146
|
+
const accentPart = (text: string) => fgCollapsed(theme, nameColor, text);
|
|
1147
|
+
const emojiPart = emoji ? `${accentPart(emoji)} ` : "";
|
|
1148
|
+
const profilePart = step.profile
|
|
1149
|
+
? accentPart(`[${sanitizeInline(step.profile)}]`)
|
|
1150
|
+
: "";
|
|
1151
|
+
return `${emojiPart}${profilePart}${accentPart(`[${sanitizeInline(name)}]`)}`;
|
|
1152
|
+
};
|
|
1119
1153
|
const detailColor = failed ? "error" : "toolOutput";
|
|
1120
|
-
const
|
|
1121
|
-
fgCollapsed(
|
|
1122
|
-
theme,
|
|
1123
|
-
detailColor,
|
|
1124
|
-
`${step.profile ? ` [${sanitizeInline(step.profile)}]` : ""} ${subagentStepPreview(step.task)}`,
|
|
1125
|
-
);
|
|
1154
|
+
const previewOf = (step: SubagentStep) =>
|
|
1155
|
+
fgCollapsed(theme, detailColor, ` ${subagentStepPreview(step.task)}`);
|
|
1126
1156
|
|
|
1127
1157
|
const marker = `${fgCollapsed(theme, color, SUBAGENT_MARKER, true)} `;
|
|
1128
1158
|
const budget = Math.max(1, width - visibleWidth(marker));
|
|
@@ -1146,14 +1176,7 @@ function renderSubagentPlan(
|
|
|
1146
1176
|
|
|
1147
1177
|
if (plan.kind === "single") {
|
|
1148
1178
|
const step = plan.steps[0]!;
|
|
1149
|
-
return [
|
|
1150
|
-
headline(
|
|
1151
|
-
fgCollapsed(theme, failed ? "error" : "toolTitle", "subagent", true) +
|
|
1152
|
-
" " +
|
|
1153
|
-
displayOf(step.agent) +
|
|
1154
|
-
detailOf(step),
|
|
1155
|
-
),
|
|
1156
|
-
];
|
|
1179
|
+
return [headline(identityOf(step) + previewOf(step))];
|
|
1157
1180
|
}
|
|
1158
1181
|
|
|
1159
1182
|
const kindLabel =
|
|
@@ -1175,7 +1198,7 @@ function renderSubagentPlan(
|
|
|
1175
1198
|
plan.kind === "chain"
|
|
1176
1199
|
? `${fgCollapsed(theme, color, `${index + 1}.`)} `
|
|
1177
1200
|
: "";
|
|
1178
|
-
lines.push(` ${number}${
|
|
1201
|
+
lines.push(` ${number}${identityOf(step)}${previewOf(step)}`);
|
|
1179
1202
|
}
|
|
1180
1203
|
if (plan.steps.length > shown.length) {
|
|
1181
1204
|
lines.push(
|
|
@@ -1263,10 +1286,11 @@ function renderGroupedCallLines(
|
|
|
1263
1286
|
rows: ToolExecutionRow[],
|
|
1264
1287
|
width: number,
|
|
1265
1288
|
theme: ThemeLike,
|
|
1266
|
-
): string[] {
|
|
1267
|
-
const lines: string[] = [];
|
|
1289
|
+
): Array<{ row: ToolExecutionRow; lines: string[] }> {
|
|
1290
|
+
const segments: Array<{ row: ToolExecutionRow; lines: string[] }> = [];
|
|
1268
1291
|
let previousToolName: string | undefined;
|
|
1269
1292
|
for (const row of rows) {
|
|
1293
|
+
const lines: string[] = [];
|
|
1270
1294
|
const toolName = row.toolName ?? "tool";
|
|
1271
1295
|
if (toolName !== previousToolName) {
|
|
1272
1296
|
lines.push(
|
|
@@ -1289,8 +1313,9 @@ function renderGroupedCallLines(
|
|
|
1289
1313
|
);
|
|
1290
1314
|
if (row.toolName === "edit")
|
|
1291
1315
|
lines.push(...renderedEditDiffLines(row, theme));
|
|
1316
|
+
segments.push({ row, lines });
|
|
1292
1317
|
}
|
|
1293
|
-
return
|
|
1318
|
+
return segments;
|
|
1294
1319
|
}
|
|
1295
1320
|
|
|
1296
1321
|
function sameMembers(
|
|
@@ -1316,14 +1341,24 @@ function sameMemberVersions(
|
|
|
1316
1341
|
);
|
|
1317
1342
|
}
|
|
1318
1343
|
|
|
1344
|
+
type GroupBlock = {
|
|
1345
|
+
lines: string[];
|
|
1346
|
+
// Click-routing accounting aligned with `lines`: one entry per drawn row
|
|
1347
|
+
// segment, so mouse events land on the member that owns the line.
|
|
1348
|
+
heights: Array<{ component: ToolExecutionRow; height: number }>;
|
|
1349
|
+
};
|
|
1350
|
+
|
|
1319
1351
|
function renderGroupedToolRows(
|
|
1320
1352
|
row: ToolExecutionRow,
|
|
1321
1353
|
rows: ToolExecutionRow[],
|
|
1322
1354
|
width: number,
|
|
1323
1355
|
state: PresentationPatchState,
|
|
1324
|
-
):
|
|
1356
|
+
): GroupBlock {
|
|
1325
1357
|
const theme = state.theme;
|
|
1326
|
-
if (!theme)
|
|
1358
|
+
if (!theme) {
|
|
1359
|
+
const lines = state.originalRender.call(row, width);
|
|
1360
|
+
return { lines, heights: [{ component: row, height: lines.length }] };
|
|
1361
|
+
}
|
|
1327
1362
|
const themeSample = themeSampleFor(theme);
|
|
1328
1363
|
const cached = state.groupCache.get(row);
|
|
1329
1364
|
const hasLiveMembers = rows.some(isLiveRow);
|
|
@@ -1335,32 +1370,52 @@ function renderGroupedToolRows(
|
|
|
1335
1370
|
sameMembers(cached.members, rows) &&
|
|
1336
1371
|
sameMemberVersions(rows, cached.memberVersions, state)
|
|
1337
1372
|
) {
|
|
1338
|
-
return cached.lines;
|
|
1373
|
+
return { lines: cached.lines, heights: cached.heights };
|
|
1339
1374
|
}
|
|
1340
1375
|
|
|
1341
1376
|
const layout = insetLayout(width);
|
|
1342
|
-
const
|
|
1343
|
-
const lines = [
|
|
1377
|
+
const segments = renderGroupedCallLines(rows, layout.contentWidth, theme);
|
|
1378
|
+
const lines = [
|
|
1379
|
+
"",
|
|
1380
|
+
...insetLines(
|
|
1381
|
+
segments.flatMap((s) => s.lines),
|
|
1382
|
+
width,
|
|
1383
|
+
),
|
|
1384
|
+
];
|
|
1385
|
+
// The leading blank and the first segment (tool-name header + call line)
|
|
1386
|
+
// both belong to the first member; every later member owns its lines.
|
|
1387
|
+
const heights = segments.map((segment, index) => ({
|
|
1388
|
+
component: segment.row,
|
|
1389
|
+
height: index === 0 ? segment.lines.length + 1 : segment.lines.length,
|
|
1390
|
+
}));
|
|
1344
1391
|
if (hasLiveMembers) {
|
|
1345
1392
|
state.groupCache.delete(row);
|
|
1346
1393
|
} else {
|
|
1347
1394
|
state.groupCache.set(row, {
|
|
1348
1395
|
lines,
|
|
1396
|
+
heights,
|
|
1349
1397
|
members: [...rows],
|
|
1350
1398
|
memberVersions: rows.map((member) => state.rowVersions.get(member) ?? 0),
|
|
1351
1399
|
themeSample,
|
|
1352
1400
|
width,
|
|
1353
1401
|
});
|
|
1354
1402
|
}
|
|
1355
|
-
return lines;
|
|
1403
|
+
return { lines, heights };
|
|
1356
1404
|
}
|
|
1357
1405
|
|
|
1406
|
+
type ContainerRender = {
|
|
1407
|
+
lines: string[];
|
|
1408
|
+
// Click-routing accounting aligned with `lines`.
|
|
1409
|
+
heights: Array<{ component: unknown; height: number }>;
|
|
1410
|
+
};
|
|
1411
|
+
|
|
1358
1412
|
function renderContainerWithToolGroups(
|
|
1359
1413
|
children: unknown[],
|
|
1360
1414
|
width: number,
|
|
1361
1415
|
presentation: PresentationPatchState,
|
|
1362
|
-
):
|
|
1416
|
+
): ContainerRender {
|
|
1363
1417
|
const lines: string[] = [];
|
|
1418
|
+
const heights: Array<{ component: unknown; height: number }> = [];
|
|
1364
1419
|
const rendered = new Map<number, string[]>();
|
|
1365
1420
|
const renderAt = (index: number): string[] => {
|
|
1366
1421
|
const cached = rendered.get(index);
|
|
@@ -1376,7 +1431,9 @@ function renderContainerWithToolGroups(
|
|
|
1376
1431
|
!isToolExecutionRow(child) ||
|
|
1377
1432
|
!isGroupableToolRow(child, children, index, renderAt, presentation)
|
|
1378
1433
|
) {
|
|
1379
|
-
|
|
1434
|
+
const drawn = renderAt(index);
|
|
1435
|
+
lines.push(...drawn);
|
|
1436
|
+
heights.push({ component: child, height: drawn.length });
|
|
1380
1437
|
continue;
|
|
1381
1438
|
}
|
|
1382
1439
|
|
|
@@ -1411,7 +1468,9 @@ function renderContainerWithToolGroups(
|
|
|
1411
1468
|
}
|
|
1412
1469
|
|
|
1413
1470
|
if (group.length === 1) {
|
|
1414
|
-
|
|
1471
|
+
const drawn = renderAt(index);
|
|
1472
|
+
lines.push(...drawn);
|
|
1473
|
+
heights.push({ component: child, height: drawn.length });
|
|
1415
1474
|
continue;
|
|
1416
1475
|
}
|
|
1417
1476
|
|
|
@@ -1419,11 +1478,13 @@ function renderContainerWithToolGroups(
|
|
|
1419
1478
|
// Use a live member while any call is pending, then the first member once
|
|
1420
1479
|
// settled. Either way, the grouped row keeps the same number of lines.
|
|
1421
1480
|
const shellRow = group.find(isLiveRow) ?? child;
|
|
1422
|
-
|
|
1481
|
+
const block = renderGroupedToolRows(shellRow, group, width, presentation);
|
|
1482
|
+
lines.push(...block.lines);
|
|
1483
|
+
heights.push(...block.heights);
|
|
1423
1484
|
index = lastMemberIndex;
|
|
1424
1485
|
}
|
|
1425
1486
|
|
|
1426
|
-
return lines;
|
|
1487
|
+
return { lines, heights };
|
|
1427
1488
|
}
|
|
1428
1489
|
|
|
1429
1490
|
// TODO: Replace prototype patching with a public Pi tool/transcript rendering API when available.
|
|
@@ -1468,11 +1529,20 @@ function installGroupingPatch(
|
|
|
1468
1529
|
// inset) decorate children through the shared hooks before grouping
|
|
1469
1530
|
// rewrites the rows; delegation alone cannot reach them from here.
|
|
1470
1531
|
restoreHooks = runChatContainerHooks(this, children, width);
|
|
1471
|
-
|
|
1532
|
+
const drawn = renderContainerWithToolGroups(
|
|
1472
1533
|
children,
|
|
1473
1534
|
width,
|
|
1474
1535
|
state.presentation,
|
|
1475
1536
|
);
|
|
1537
|
+
// The grouping path bypasses the native render that refreshes the
|
|
1538
|
+
// container's mouse-layout cache. Publish the drawn accounting so
|
|
1539
|
+
// click-to-expand (Pi routes by per-child line heights) keeps landing
|
|
1540
|
+
// on the row that actually owns the line, including grouped members.
|
|
1541
|
+
(this as { mouseLayout?: unknown }).mouseLayout = {
|
|
1542
|
+
width,
|
|
1543
|
+
children: drawn.heights,
|
|
1544
|
+
};
|
|
1545
|
+
return drawn.lines;
|
|
1476
1546
|
} catch {
|
|
1477
1547
|
return state.originalRender.call(this, width);
|
|
1478
1548
|
} finally {
|
|
@@ -1559,6 +1629,34 @@ function installPresentationPatch(): PresentationPatchState | undefined {
|
|
|
1559
1629
|
state.collapsedCache.delete(this);
|
|
1560
1630
|
state.originalUpdateDisplay.call(this);
|
|
1561
1631
|
};
|
|
1632
|
+
// Pi 0.85 wraps settled tool results in a click-to-expand MouseRegion.
|
|
1633
|
+
// The custom collapsed row replaces those lines with a single summary, so
|
|
1634
|
+
// the region never receives the click; toggle expansion here instead.
|
|
1635
|
+
let patchedHandleMouse:
|
|
1636
|
+
| ((this: ToolExecutionRow, event: unknown) => unknown)
|
|
1637
|
+
| undefined;
|
|
1638
|
+
if (typeof proto.handleMouse === "function") {
|
|
1639
|
+
state.originalHandleMouse = proto.handleMouse;
|
|
1640
|
+
patchedHandleMouse = function handleMouseWithCollapsedToggle(
|
|
1641
|
+
this: ToolExecutionRow,
|
|
1642
|
+
event: unknown,
|
|
1643
|
+
): unknown {
|
|
1644
|
+
const mouseEvent = event as { type?: unknown; button?: unknown };
|
|
1645
|
+
if (
|
|
1646
|
+
state.theme &&
|
|
1647
|
+
this.expanded === false &&
|
|
1648
|
+
!!this.result &&
|
|
1649
|
+
mouseEvent?.type === "click" &&
|
|
1650
|
+
mouseEvent.button === "left" &&
|
|
1651
|
+
typeof this.setExpanded === "function"
|
|
1652
|
+
) {
|
|
1653
|
+
this.setExpanded(true);
|
|
1654
|
+
return { handled: true };
|
|
1655
|
+
}
|
|
1656
|
+
return state.originalHandleMouse?.call(this, event);
|
|
1657
|
+
};
|
|
1658
|
+
proto.handleMouse = patchedHandleMouse;
|
|
1659
|
+
}
|
|
1562
1660
|
const patchedRender = function renderWithToolPresentation(
|
|
1563
1661
|
this: ToolExecutionRow,
|
|
1564
1662
|
width: number,
|
|
@@ -1665,6 +1763,7 @@ function uninstallPresentationPatch(
|
|
|
1665
1763
|
[PRESENTATION_PATCHED]?: PresentationPatchState;
|
|
1666
1764
|
render?: (width: number) => string[];
|
|
1667
1765
|
updateDisplay?: () => void;
|
|
1766
|
+
handleMouse?: (event: unknown) => unknown;
|
|
1668
1767
|
};
|
|
1669
1768
|
if (
|
|
1670
1769
|
proto[PRESENTATION_PATCHED] !== state ||
|
|
@@ -1675,6 +1774,16 @@ function uninstallPresentationPatch(
|
|
|
1675
1774
|
}
|
|
1676
1775
|
proto.render = state.originalRender;
|
|
1677
1776
|
proto.updateDisplay = state.originalUpdateDisplay;
|
|
1777
|
+
if (
|
|
1778
|
+
state.patchedHandleMouse &&
|
|
1779
|
+
proto.handleMouse === state.patchedHandleMouse
|
|
1780
|
+
) {
|
|
1781
|
+
if (state.originalHandleMouse) {
|
|
1782
|
+
proto.handleMouse = state.originalHandleMouse;
|
|
1783
|
+
} else {
|
|
1784
|
+
delete proto.handleMouse;
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1678
1787
|
delete proto[PRESENTATION_PATCHED];
|
|
1679
1788
|
}
|
|
1680
1789
|
|