pi-cc-extensions 0.8.36 → 0.8.37

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.
@@ -1126,6 +1126,13 @@ function useFixedEditorFeatures(tui: any): boolean {
1126
1126
  return toolMouseFixedFeaturesEnabled && isFixedEditorTui(tui);
1127
1127
  }
1128
1128
 
1129
+ /** Mouse hover/click affordances need ccstyle rendering AND the fixed editor. Without
1130
+ * the fixed editor, Pi's native TUI has no mouse handling, so any reporting mode leaves
1131
+ * the wheel in a dead zone — native mode must leave reporting off entirely. */
1132
+ function toolMouseInteractionActive(): boolean {
1133
+ return config.mode !== "off" && toolMouseFixedFeaturesEnabled;
1134
+ }
1135
+
1129
1136
  function formatShortcut(shortcut: string): string {
1130
1137
  return shortcut
1131
1138
  .split("+")
@@ -1249,7 +1256,12 @@ function hideScrollButton(tui: any): void {
1249
1256
  }
1250
1257
 
1251
1258
  function scheduleScrollButtonSync(tui: any, data: string): void {
1252
- if (!useFixedEditorFeatures(tui) || !isScrollNavigationInput(data) || scrollButtonSyncScheduled)
1259
+ if (
1260
+ !useFixedEditorFeatures(tui) ||
1261
+ !toolMouseInteractionActive() ||
1262
+ !isScrollNavigationInput(data) ||
1263
+ scrollButtonSyncScheduled
1264
+ )
1253
1265
  return;
1254
1266
  scrollButtonSyncScheduled = true;
1255
1267
  const previousLines = tui.previousLines;
@@ -1278,7 +1290,7 @@ function scheduleScrollButtonSync(tui: any, data: string): void {
1278
1290
  }
1279
1291
 
1280
1292
  function updateScrollButtonFromInput(tui: any, data: string): void {
1281
- if (!useFixedEditorFeatures(tui)) return;
1293
+ if (!useFixedEditorFeatures(tui) || !toolMouseInteractionActive()) return;
1282
1294
  if (matchesKey(data, "enter") || matchesKey(data, "return")) hideScrollButton(tui);
1283
1295
  }
1284
1296
 
@@ -1521,7 +1533,7 @@ function patchToolMouseInputCapture(tui: any): void {
1521
1533
  )
1522
1534
  return;
1523
1535
  const packets = parseSgrMousePackets(data);
1524
- if (packets) {
1536
+ if (packets && toolMouseInteractionActive()) {
1525
1537
  for (const packet of packets) {
1526
1538
  // Fixed-editor owners may consume motion before extension listeners run,
1527
1539
  // so hover must be handled at the root input boundary too.
@@ -1810,7 +1822,8 @@ function patchToolMouseMotionAfterRender(tui: any): void {
1810
1822
  this.previousLines = extracted.lines;
1811
1823
  placements = extracted.placements;
1812
1824
  }
1813
- if (!useFixedEditorFeatures(this)) toolMouseRawWrite?.(TOOL_MOUSE_MOTION_ENABLE);
1825
+ if (!useFixedEditorFeatures(this) && toolMouseInteractionActive())
1826
+ toolMouseRawWrite?.(TOOL_MOUSE_MOTION_ENABLE);
1814
1827
  return result;
1815
1828
  } finally {
1816
1829
  activeIoViewFrame = previousFrame;
@@ -1833,7 +1846,8 @@ function patchToolMouseMotionAfterRender(tui: any): void {
1833
1846
  toolMouseRenderPatchOriginal = original;
1834
1847
  toolMouseRenderPatchWrapper = wrapper;
1835
1848
  toolMouseRenderPatchState = patchState;
1836
- if (!useFixedEditorFeatures(tui)) toolMouseRawWrite?.(TOOL_MOUSE_MOTION_ENABLE);
1849
+ if (!useFixedEditorFeatures(tui) && toolMouseInteractionActive())
1850
+ toolMouseRawWrite?.(TOOL_MOUSE_MOTION_ENABLE);
1837
1851
  }
1838
1852
 
1839
1853
  function handleToolMouseInput(data: string): { consume: true } | undefined {
@@ -1857,6 +1871,9 @@ function handleToolMouseInput(data: string): { consume: true } | undefined {
1857
1871
  return { consume: true };
1858
1872
  }
1859
1873
  }
1874
+ // Off mode restores native input: wheel keeps scrolling through Pi's normal
1875
+ // dispatcher, while hover/click affordances are entirely inactive.
1876
+ if (!toolMouseInteractionActive()) return undefined;
1860
1877
  const packets = parseSgrMousePackets(data);
1861
1878
  if (!packets) {
1862
1879
  scheduleScrollButtonSync(toolMouseTui, data);
@@ -1892,7 +1909,7 @@ function teardownToolMouseInteraction(nextFixedEditorFeatures = false): void {
1892
1909
  setHoveredToolGroup(null);
1893
1910
  setHoveredToolIo(null, null);
1894
1911
  try {
1895
- if (!toolMouseFixedFeaturesEnabled && !nextFixedEditorFeatures) {
1912
+ if (!nextFixedEditorFeatures) {
1896
1913
  toolMouseTui?.terminal?.write?.(TOOL_MOUSE_DISABLE);
1897
1914
  }
1898
1915
  } catch {
@@ -1932,13 +1949,17 @@ export function installToolMouseInteraction(
1932
1949
  toolMouseFixedFeaturesEnabled = fixedEditorFeatures;
1933
1950
  ctx.ui.setWidget(TOOL_MOUSE_WIDGET_KEY, (tui: any, theme: any) => {
1934
1951
  toolMouseTui = tui;
1935
- if (fixedEditorFeatures) patchToolMouseInputCapture(tui);
1936
- // Fixed mode: wrap only after compositor install makes features live.
1937
- if (!fixedEditorFeatures || useFixedEditorFeatures(tui)) {
1938
- patchToolMouseMotionAfterRender(tui);
1939
- }
1940
- // The fixed-editor compositor owns its mouse mode; native Pi still needs motion enabled.
1941
- if (!fixedEditorFeatures) tui?.terminal?.write?.(TOOL_MOUSE_MOTION_ENABLE);
1952
+ // Root input capture follows the live compositor; onRebuild re-applies it
1953
+ // once the fixed-editor compositor actually owns the terminal.
1954
+ if (useFixedEditorFeatures(tui)) patchToolMouseInputCapture(tui);
1955
+ // Wrap doRender unconditionally: the fixed-editor rebuild replaces the
1956
+ // chain (setBeforeFixedEditorStart restores it first) and onRebuild
1957
+ // re-applies this wrapper once the compositor owns the terminal.
1958
+ patchToolMouseMotionAfterRender(tui);
1959
+ // The fixed-editor compositor owns its mouse mode; native Pi gets motion only
1960
+ // while mouse interaction is active (rendering mode on + fixed editor).
1961
+ if (!fixedEditorFeatures && toolMouseInteractionActive())
1962
+ tui?.terminal?.write?.(TOOL_MOUSE_MOTION_ENABLE);
1942
1963
  const widget = {
1943
1964
  render: (width: number) => renderScrollButton(width, theme),
1944
1965
  invalidate() {},
@@ -1998,6 +2019,21 @@ function applyStyleMode(
1998
2019
  ): void {
1999
2020
  config.mode = mode;
2000
2021
  saveConfig();
2022
+ if (mode === "off") {
2023
+ // Native rendering mode: drop hover/click state and fully disable mouse
2024
+ // reporting so the terminal restores its default scrollback wheel scrolling.
2025
+ // (The fixed-editor compositor owns its own reporting when enabled.)
2026
+ hoveredToolCallId = null;
2027
+ setHoveredToolGroup(null);
2028
+ setHoveredToolIo(null, null);
2029
+ scrollButtonVisible = false;
2030
+ scrollButtonHovered = false;
2031
+ pendingScrollMessages = 0;
2032
+ assistantMessageActive = false;
2033
+ if (toolMouseTui && !useFixedEditorFeatures(toolMouseTui)) {
2034
+ toolMouseTui.terminal?.write?.(TOOL_MOUSE_DISABLE);
2035
+ }
2036
+ }
2001
2037
  refreshCurrentTranscript(compactStyle, ctx, toolGrouping);
2002
2038
  ctx.ui.notify(`Claude Code style: ${mode}`, "info");
2003
2039
  }
@@ -2015,7 +2051,7 @@ function modeSettingDescription(mode: CompactStyleMode): string {
2015
2051
  function fixedEditorSettingDescription(enabled: boolean): string {
2016
2052
  return enabled
2017
2053
  ? "Pinned editor via @tifan/pi-fixed-editor. Mouse capture, 5-row wheel, tool clicks, back-to-bottom button, message count, and Ctrl+End."
2018
- : "Native scrolling editor; fixed-editor mouse features and button off. Ctrl+End remains enabled.";
2054
+ : "Native scrolling editor; mouse hover/click and wheel reporting off. Ctrl+End remains enabled.";
2019
2055
  }
2020
2056
 
2021
2057
  function excludeRenderersDescription(names: readonly string[]): string {
@@ -122,8 +122,11 @@ export default function (pi: ExtensionAPI): void {
122
122
  if (!turnActive || refreshTimer) return;
123
123
  refreshTimer = setTimeout(() => {
124
124
  refreshTimer = null;
125
- syncWorkingMessage();
126
- scheduleRefreshTick();
125
+ try {
126
+ syncWorkingMessage();
127
+ } finally {
128
+ scheduleRefreshTick();
129
+ }
127
130
  }, REFRESH_INTERVAL_MS);
128
131
  refreshTimer.unref?.();
129
132
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-cc-extensions",
3
- "version": "0.8.36",
3
+ "version": "0.8.37",
4
4
  "description": "A Pi productivity suite with Claude Code-style UI, fixed editor, context inspection, and agent/session references",
5
5
  "type": "module",
6
6
  "keywords": [