pi-cc-extensions 0.8.10 → 0.8.11

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/README.md CHANGED
@@ -85,7 +85,7 @@
85
85
  }
86
86
  ```
87
87
 
88
- `mode` 可取 `on`、`off` 或 `compact`。`fixedEditorFeatures` 默认为 `true`,启用 fixed editor 的工具鼠标点击、滚动到底部按钮、消息计数和专用 viewport 映射;设为 `false` 后关闭终端鼠标上报及上述功能,让非 fixed editor 恢复终端原生滚轮滚动(工具仍可通过键盘展开)。`Ctrl+End` 在两种模式下均保留。旧版 `enabled: true/false` 会自动迁移为 `on/off`。排除名单使用精确工具名;手动修改配置后执行 `/reload`。`Agent` 的专用 renderer 始终保留。
88
+ `mode` 可取 `on`、`off` 或 `compact`。`fixedEditorFeatures` 默认为 `true`,启用 fixed editor 的每刻度 5 行滚动、工具鼠标点击、收起位置补偿、滚动到底部按钮、消息计数和专用 viewport 映射;设为 `false` 后关闭终端鼠标上报及上述功能,让非 fixed editor 恢复终端原生滚轮滚动(工具仍可通过键盘展开)。`Ctrl+End` 在两种模式下均保留。旧版 `enabled: true/false` 会自动迁移为 `on/off`。排除名单使用精确工具名;手动修改配置后执行 `/reload`。`Agent` 的专用 renderer 始终保留。
89
89
 
90
90
  Compact transcript 行为改编自 [avhagedorn/pi-compact-transcript](https://github.com/avhagedorn/pi-compact-transcript) v0.6.2(MIT,Alan Hagedorn)。
91
91
 
@@ -333,9 +333,14 @@ const TOOL_MOUSE_DISABLE = "\x1b[?1006l\x1b[?1000l";
333
333
  const ZENTUI_PAGE_UP_INPUT = /^\x1b\[5;9(?::[12])?~$|^\x1b\[57421;9(?::[12])?u$|^\x1b\[1;6A$/;
334
334
  const ZENTUI_PAGE_DOWN_INPUT = /^\x1b\[6;9(?::[12])?~$|^\x1b\[57422;9(?::[12])?u$|^\x1b\[1;6B$/;
335
335
  const SCROLL_BOTTOM_SHORTCUT = "ctrl+end";
336
+ const ZENTUI_WHEEL_ROWS = 3;
337
+ const FIXED_EDITOR_WHEEL_ROWS = 5;
336
338
  let toolMouseTui: any = null;
337
339
  let toolMouseUi: any = null;
338
340
  let toolMouseFixedFeaturesEnabled = false;
341
+ let wheelExtraRowRemainder = 0;
342
+ let lastWheelDirection: "up" | "down" | null = null;
343
+ let collapseCompensationRemainder = 0;
339
344
  let toolMouseInputUnsubscribe: (() => void) | null = null;
340
345
  let toolMouseInputPatchTui: any = null;
341
346
  let toolMouseInputPatchOriginalHandle: ((...args: any[]) => any) | null = null;
@@ -558,6 +563,29 @@ function isScrollBottomInput(data: string): boolean {
558
563
  return matchesKey(data, SCROLL_BOTTOM_SHORTCUT);
559
564
  }
560
565
 
566
+ function wheelDirection(data: string): "up" | "down" | null {
567
+ const packets = parseSgrMousePackets(data);
568
+ for (const packet of packets ?? []) {
569
+ if (packet.final !== "M") continue;
570
+ const baseButton = packet.code & ~(4 | 8 | 16 | 32);
571
+ if (baseButton === 64) return "up";
572
+ if (baseButton === 65) return "down";
573
+ }
574
+ return null;
575
+ }
576
+
577
+ /** Return how often Zentui's 3-row wheel handler should receive this event. */
578
+ export function fixedEditorWheelDispatchCount(direction: "up" | "down"): number {
579
+ if (lastWheelDirection !== direction) {
580
+ lastWheelDirection = direction;
581
+ wheelExtraRowRemainder = 0;
582
+ }
583
+ wheelExtraRowRemainder += FIXED_EDITOR_WHEEL_ROWS - ZENTUI_WHEEL_ROWS;
584
+ if (wheelExtraRowRemainder < ZENTUI_WHEEL_ROWS) return 1;
585
+ wheelExtraRowRemainder -= ZENTUI_WHEEL_ROWS;
586
+ return 2;
587
+ }
588
+
561
589
  function isScrollNavigationInput(data: string): boolean {
562
590
  if (
563
591
  matchesKey(data, "pageUp") ||
@@ -822,14 +850,41 @@ function handleScrollButtonClick(tui: any, packet: SgrMousePacket): boolean {
822
850
  return jumpToBottomWithoutSubmit(tui);
823
851
  }
824
852
 
853
+ function scheduleCollapseViewportCompensation(
854
+ tui: any,
855
+ removedRows: number,
856
+ packet: SgrMousePacket,
857
+ ): void {
858
+ if (removedRows <= 0 || !useFixedEditorFeatures(tui)) return;
859
+ const originalHandle = toolMouseInputPatchTui === tui ? toolMouseInputPatchOriginalHandle : null;
860
+ if (!originalHandle) return;
861
+
862
+ process.nextTick(() => {
863
+ if (toolMouseTui !== tui || toolMouseInputPatchOriginalHandle !== originalHandle) return;
864
+ const targetRows = removedRows + collapseCompensationRemainder;
865
+ const dispatches = Math.max(0, Math.round(targetRows / ZENTUI_WHEEL_ROWS));
866
+ collapseCompensationRemainder = targetRows - dispatches * ZENTUI_WHEEL_ROWS;
867
+ const wheelDown = `\x1b[<65;${packet.col};${packet.row}M`;
868
+ for (let index = 0; index < dispatches; index++) {
869
+ Reflect.apply(originalHandle, tui, [wheelDown]);
870
+ }
871
+ });
872
+ }
873
+
825
874
  function toggleToolAtMouseClick(tui: any, packet: SgrMousePacket): boolean {
826
875
  const hit = findToolAtScreenRow(tui, packet.row);
827
876
  if (!hit) return false;
828
877
 
829
- const nextExpanded = !Boolean(hit.component.expanded);
830
- hit.component.setExpanded(nextExpanded);
878
+ const wasExpanded = Boolean(hit.component.expanded);
879
+ const width = Math.max(1, Number(tui?.terminal?.columns) || 80);
880
+ const previousHeight = wasExpanded ? renderComponentTree(hit.component, width).length : 0;
881
+ hit.component.setExpanded(!wasExpanded);
831
882
  hit.component.invalidate?.();
883
+ const nextHeight = wasExpanded ? renderComponentTree(hit.component, width).length : 0;
832
884
  tui.requestRender?.();
885
+ if (wasExpanded) {
886
+ scheduleCollapseViewportCompensation(tui, previousHeight - nextHeight, packet);
887
+ }
833
888
  return true;
834
889
  }
835
890
 
@@ -878,7 +933,13 @@ function patchToolMouseInputCapture(tui: any): void {
878
933
  }
879
934
  }
880
935
  }
881
- const result = Reflect.apply(originalHandle, this, args);
936
+ const direction =
937
+ typeof data === "string" && useFixedEditorFeatures(this) ? wheelDirection(data) : null;
938
+ const dispatchCount = direction ? fixedEditorWheelDispatchCount(direction) : 1;
939
+ let result = Reflect.apply(originalHandle, this, args);
940
+ for (let index = 1; index < dispatchCount; index++) {
941
+ result = Reflect.apply(originalHandle, this, args);
942
+ }
882
943
  if (typeof data === "string") scheduleScrollButtonSync(this, data);
883
944
  return result;
884
945
  };
@@ -971,6 +1032,9 @@ function teardownToolMouseInteraction(): void {
971
1032
  toolMouseTui = null;
972
1033
  toolMouseUi = null;
973
1034
  toolMouseFixedFeaturesEnabled = false;
1035
+ wheelExtraRowRemainder = 0;
1036
+ lastWheelDirection = null;
1037
+ collapseCompensationRemainder = 0;
974
1038
  }
975
1039
 
976
1040
  export function installToolMouseInteraction(
@@ -1044,7 +1108,7 @@ function modeSettingDescription(mode: CompactStyleMode): string {
1044
1108
 
1045
1109
  function fixedEditorSettingDescription(enabled: boolean): string {
1046
1110
  return enabled
1047
- ? "Enables mouse capture, tool click expansion, fixed viewport mapping, the back-to-bottom button, message count, and Ctrl+End."
1111
+ ? "Enables mouse capture, 5-row wheel scrolling, tool click expansion with collapse anchoring, fixed viewport mapping, the back-to-bottom button, message count, and Ctrl+End."
1048
1112
  : "Uses terminal-native wheel scrolling; disables mouse capture, tool clicks, fixed viewport mapping, button, and message count. Ctrl+End remains enabled.";
1049
1113
  }
1050
1114
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-cc-extensions",
3
- "version": "0.8.10",
3
+ "version": "0.8.11",
4
4
  "description": "A Pi productivity suite with Claude Code-style UI, structured questionnaires, context inspection, and agent/session references",
5
5
  "type": "module",
6
6
  "keywords": [