pi-view-image 0.3.7 → 0.3.8

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.
Files changed (346) hide show
  1. package/README.md +21 -13
  2. package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/README.md +10 -12
  3. package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/package.json +13 -10
  4. package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/contributions/xsettings.ts +1 -1
  5. package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/host/binary.ts +1 -1
  6. package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/protocol/nested-tools.ts +1 -1
  7. package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/ui/presentation.ts +3 -3
  8. package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/test/ui/presentation.test.ts +3 -3
  9. package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/README.md +81 -29
  10. package/node_modules/@luan.sh/pi-libtui/native-revision +1 -0
  11. package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/package.json +8 -5
  12. package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/native-binary.ts +8 -8
  13. package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/panels.ts +2 -2
  14. package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/editor-chrome.test.ts +2 -2
  15. package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/native-binary.test.ts +1 -1
  16. package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/public-surface.test.ts +11 -11
  17. package/package.json +12 -9
  18. package/src/code-mode-adapter.ts +1 -1
  19. package/src/core/appearance.ts +1 -1
  20. package/src/extension.ts +15 -4
  21. package/src/image-limits.ts +57 -0
  22. package/src/native/binary.ts +2 -2
  23. package/src/runtime/editor-attachments.ts +2 -2
  24. package/src/tools/view-image/presentation.ts +2 -2
  25. package/test/image-limits.test.ts +50 -0
  26. package/test/view-image.test.ts +3 -3
  27. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/LICENSE +0 -0
  28. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/extension.ts +0 -0
  29. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/host/cell-operations.ts +0 -0
  30. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/host/client.ts +0 -0
  31. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/host/connection.ts +0 -0
  32. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/host/delegation.ts +0 -0
  33. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/host/operation.ts +0 -0
  34. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/host/process.ts +0 -0
  35. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/host/protocol.ts +0 -0
  36. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/host/session.ts +0 -0
  37. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/index.ts +0 -0
  38. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/protocol/hierarchy.ts +0 -0
  39. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/protocol/preflights.ts +0 -0
  40. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/protocol/tool-definition-adapter.ts +0 -0
  41. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/protocol/types.ts +0 -0
  42. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/runtime/code-mode.ts +0 -0
  43. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/runtime/delegation.ts +0 -0
  44. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/runtime/lifecycle.ts +0 -0
  45. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/runtime/trace-values.ts +0 -0
  46. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/sdk.ts +0 -0
  47. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/tools/exec/definition.ts +0 -0
  48. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/tools/exec/description.ts +0 -0
  49. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/tools/exec/grammar.ts +0 -0
  50. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/tools/result.ts +0 -0
  51. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/src/tools/wait/definition.ts +0 -0
  52. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/test/extension.test.ts +0 -0
  53. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/test/host/integration.test.ts +0 -0
  54. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/test/host/protocol.test.ts +0 -0
  55. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/test/protocol/nested-tools.test.ts +0 -0
  56. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/test/protocol/preflights.test.ts +0 -0
  57. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/test/runtime/delegation.test.ts +0 -0
  58. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/test/runtime/trace-values.test.ts +0 -0
  59. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/test/tool-definition-adapter.test.ts +0 -0
  60. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/test/tools/result.test.ts +0 -0
  61. /package/node_modules/{@cfcluan → @luan.sh}/pi-code-mode/tsconfig.json +0 -0
  62. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/LICENSE +0 -0
  63. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/activity-presentation.ts +0 -0
  64. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/appearance.ts +0 -0
  65. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/background-surface.ts +0 -0
  66. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/color/palette.ts +0 -0
  67. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/color/preview.ts +0 -0
  68. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/color/resolver.ts +0 -0
  69. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/color/theme.ts +0 -0
  70. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/component-stack.ts +0 -0
  71. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/content/markdown-code.ts +0 -0
  72. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/content/terminal-text.ts +0 -0
  73. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/content/text.ts +0 -0
  74. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/controls/action-panel.ts +0 -0
  75. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/controls/dialog-button-bar.ts +0 -0
  76. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/controls/multi-select.ts +0 -0
  77. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/controls/picker-panel.ts +0 -0
  78. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/controls/screen-icon-actions.ts +0 -0
  79. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/controls/searchable-select.ts +0 -0
  80. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/controls/select-box.ts +0 -0
  81. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/controls/selectable-list.ts +0 -0
  82. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/controls/selection-action-bar.ts +0 -0
  83. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/controls/semantic-input.ts +0 -0
  84. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/controls/tab.ts +0 -0
  85. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/cursor.ts +0 -0
  86. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/decoration/editor-pills.ts +0 -0
  87. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/decoration/glyphs.ts +0 -0
  88. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/decoration/pointer-interaction.ts +0 -0
  89. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/decoration/powerline-pill.ts +0 -0
  90. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/decoration/status.ts +0 -0
  91. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/decoration/transient-pill.ts +0 -0
  92. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/diff/index.ts +0 -0
  93. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/diff/model.ts +0 -0
  94. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/diff/parse.ts +0 -0
  95. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/diff/pierre-syntax.ts +0 -0
  96. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/diff/render.ts +0 -0
  97. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/diff/structured.ts +0 -0
  98. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/diff/view.ts +0 -0
  99. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/editor/chrome.ts +0 -0
  100. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/editor/composition.ts +0 -0
  101. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/editor/layout.ts +0 -0
  102. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/editor/presentation.ts +0 -0
  103. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/editor/protocol.ts +0 -0
  104. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/editor.ts +0 -0
  105. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/extension.ts +0 -0
  106. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/folding.ts +0 -0
  107. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/host/cursor-bridge.ts +0 -0
  108. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/host/editor-bridge.ts +0 -0
  109. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/host/extension-host.ts +0 -0
  110. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/host/mouse-bridge.ts +0 -0
  111. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/host/mouse-dispatch.ts +0 -0
  112. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/host/mouse-input.ts +0 -0
  113. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/host/mouse-targets.ts +0 -0
  114. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/host/pi-layout-adapter.ts +0 -0
  115. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/host/pi-native-selection.ts +0 -0
  116. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/host/split-pane-bridge.ts +0 -0
  117. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/host/transcript-bridge.ts +0 -0
  118. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/index.ts +0 -0
  119. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/line-layout.ts +0 -0
  120. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/motion.ts +0 -0
  121. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/mouse/events.ts +0 -0
  122. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/mouse/fullscreen-layout.ts +0 -0
  123. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/mouse/registry.ts +0 -0
  124. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/mouse.ts +0 -0
  125. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/overlay/anchored.ts +0 -0
  126. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/overlay/detail-card.ts +0 -0
  127. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/overlay/dialog.ts +0 -0
  128. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/overlay/floating.ts +0 -0
  129. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/overlay/framed-editor.ts +0 -0
  130. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/overlay/fullscreen.ts +0 -0
  131. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/overlay/hover-tooltip.ts +0 -0
  132. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/overlay/modal-mount.ts +0 -0
  133. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/render-cache.ts +0 -0
  134. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/render-epoch.ts +0 -0
  135. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/request-animation.ts +0 -0
  136. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/scrollbar.ts +0 -0
  137. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/selection.ts +0 -0
  138. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/split-pane.ts +0 -0
  139. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/status-presentation.ts +0 -0
  140. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/stream.ts +0 -0
  141. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/syntax.ts +0 -0
  142. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/terminal/bridge-client.ts +0 -0
  143. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/terminal/embedding.ts +0 -0
  144. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/terminal/output.ts +0 -0
  145. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/terminal/projection.ts +0 -0
  146. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/terminal/pty-host.ts +0 -0
  147. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/terminal/pty-pane.ts +0 -0
  148. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/terminal-colors.ts +0 -0
  149. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/tool/action.ts +0 -0
  150. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/tool/activity.ts +0 -0
  151. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/tool/call-preview.ts +0 -0
  152. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/tool/disclosure-action.ts +0 -0
  153. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/tool/expanded-region-viewport.ts +0 -0
  154. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/tool/index.ts +0 -0
  155. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/tool/output.ts +0 -0
  156. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/tool/transcript.ts +0 -0
  157. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/src/tool/view-region.ts +0 -0
  158. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/appearance.test.ts +0 -0
  159. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/bounded-stream.test.ts +0 -0
  160. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/bridge-client.test.ts +0 -0
  161. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/color-preview.test.ts +0 -0
  162. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/component-stack.test.ts +0 -0
  163. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/components.test.ts +0 -0
  164. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/content-text.test.ts +0 -0
  165. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/cursor-bridge.test.ts +0 -0
  166. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/cursor.test.ts +0 -0
  167. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/editor-layout.test.ts +0 -0
  168. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/editor-registry.test.ts +0 -0
  169. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/editor-theme.test.ts +0 -0
  170. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/editor-token-pill.test.ts +0 -0
  171. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/floating-overlay.test.ts +0 -0
  172. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/folding.test.ts +0 -0
  173. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/harmonious-theme.test.ts +0 -0
  174. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/interaction.test.ts +0 -0
  175. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/key-icons.test.ts +0 -0
  176. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/markdown-code.test.ts +0 -0
  177. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/modal-overlay-mount.test.ts +0 -0
  178. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/motion.test.ts +0 -0
  179. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/mouse/bridge.test.ts +0 -0
  180. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/mouse/extension.test.ts +0 -0
  181. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/mouse/registry.test.ts +0 -0
  182. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/mouse/screen-decoration.test.ts +0 -0
  183. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/palette.test.ts +0 -0
  184. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/panels.test.ts +0 -0
  185. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/pointer-components.test.ts +0 -0
  186. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/progress.test.ts +0 -0
  187. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/pty-host.test.ts +0 -0
  188. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/pty-pane.test.ts +0 -0
  189. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/render-cache.test.ts +0 -0
  190. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/render-epoch.test.ts +0 -0
  191. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/request-animation.test.ts +0 -0
  192. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/screen-icon-actions.test.ts +0 -0
  193. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/select-box.test.ts +0 -0
  194. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/select-pointer.test.ts +0 -0
  195. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/selectable-list.test.ts +0 -0
  196. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/selection/registry.test.ts +0 -0
  197. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/selection-action-bar.test.ts +0 -0
  198. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/split-pane-bridge.test.ts +0 -0
  199. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/split-pane.test.ts +0 -0
  200. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/status-presentation.test.ts +0 -0
  201. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/syntax.test.ts +0 -0
  202. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/terminal-colors.test.ts +0 -0
  203. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/terminal-embedding.test.ts +0 -0
  204. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/terminal-projection.test.ts +0 -0
  205. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/theme-colors.test.ts +0 -0
  206. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/tool-output.test.ts +0 -0
  207. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/tool-transcript.test.ts +0 -0
  208. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/test/unified-diff.test.ts +0 -0
  209. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/themes/harmonious.json +0 -0
  210. /package/node_modules/{pi-libtui → @luan.sh/pi-libtui}/tsconfig.json +0 -0
  211. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/CONTRIBUTING.md +0 -0
  212. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/LICENSE +0 -0
  213. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/README.md +0 -0
  214. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/dist/diff.js +0 -0
  215. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/dist/diff.min.js +0 -0
  216. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/eslint.config.mjs +0 -0
  217. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/convert/dmp.d.ts +0 -0
  218. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/convert/dmp.d.ts.map +0 -0
  219. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/convert/dmp.js +0 -0
  220. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/convert/xml.d.ts +0 -0
  221. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/convert/xml.d.ts.map +0 -0
  222. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/convert/xml.js +0 -0
  223. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/diff/array.d.ts +0 -0
  224. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/diff/array.d.ts.map +0 -0
  225. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/diff/array.js +0 -0
  226. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/diff/base.d.ts +0 -0
  227. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/diff/base.d.ts.map +0 -0
  228. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/diff/base.js +0 -0
  229. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/diff/character.d.ts +0 -0
  230. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/diff/character.d.ts.map +0 -0
  231. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/diff/character.js +0 -0
  232. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/diff/css.d.ts +0 -0
  233. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/diff/css.d.ts.map +0 -0
  234. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/diff/css.js +0 -0
  235. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/diff/json.d.ts +0 -0
  236. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/diff/json.d.ts.map +0 -0
  237. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/diff/json.js +0 -0
  238. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/diff/line.d.ts +0 -0
  239. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/diff/line.d.ts.map +0 -0
  240. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/diff/line.js +0 -0
  241. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/diff/sentence.d.ts +0 -0
  242. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/diff/sentence.d.ts.map +0 -0
  243. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/diff/sentence.js +0 -0
  244. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/diff/word.d.ts +0 -0
  245. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/diff/word.d.ts.map +0 -0
  246. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/diff/word.js +0 -0
  247. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/index.d.ts +0 -0
  248. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/index.d.ts.map +0 -0
  249. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/index.js +0 -0
  250. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/package.json +0 -0
  251. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/patch/apply.d.ts +0 -0
  252. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/patch/apply.d.ts.map +0 -0
  253. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/patch/apply.js +0 -0
  254. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/patch/create.d.ts +0 -0
  255. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/patch/create.d.ts.map +0 -0
  256. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/patch/create.js +0 -0
  257. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/patch/line-endings.d.ts +0 -0
  258. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/patch/line-endings.d.ts.map +0 -0
  259. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/patch/line-endings.js +0 -0
  260. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/patch/parse.d.ts +0 -0
  261. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/patch/parse.d.ts.map +0 -0
  262. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/patch/parse.js +0 -0
  263. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/patch/reverse.d.ts +0 -0
  264. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/patch/reverse.d.ts.map +0 -0
  265. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/patch/reverse.js +0 -0
  266. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/types.d.ts +0 -0
  267. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/types.d.ts.map +0 -0
  268. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/types.js +0 -0
  269. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/util/array.d.ts +0 -0
  270. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/util/array.d.ts.map +0 -0
  271. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/util/array.js +0 -0
  272. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/util/distance-iterator.d.ts +0 -0
  273. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/util/distance-iterator.d.ts.map +0 -0
  274. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/util/distance-iterator.js +0 -0
  275. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/util/params.d.ts +0 -0
  276. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/util/params.d.ts.map +0 -0
  277. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/util/params.js +0 -0
  278. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/util/string.d.ts +0 -0
  279. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/util/string.d.ts.map +0 -0
  280. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libcjs/util/string.js +0 -0
  281. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/convert/dmp.d.ts +0 -0
  282. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/convert/dmp.d.ts.map +0 -0
  283. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/convert/dmp.js +0 -0
  284. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/convert/xml.d.ts +0 -0
  285. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/convert/xml.d.ts.map +0 -0
  286. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/convert/xml.js +0 -0
  287. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/diff/array.d.ts +0 -0
  288. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/diff/array.d.ts.map +0 -0
  289. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/diff/array.js +0 -0
  290. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/diff/base.d.ts +0 -0
  291. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/diff/base.d.ts.map +0 -0
  292. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/diff/base.js +0 -0
  293. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/diff/character.d.ts +0 -0
  294. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/diff/character.d.ts.map +0 -0
  295. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/diff/character.js +0 -0
  296. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/diff/css.d.ts +0 -0
  297. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/diff/css.d.ts.map +0 -0
  298. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/diff/css.js +0 -0
  299. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/diff/json.d.ts +0 -0
  300. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/diff/json.d.ts.map +0 -0
  301. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/diff/json.js +0 -0
  302. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/diff/line.d.ts +0 -0
  303. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/diff/line.d.ts.map +0 -0
  304. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/diff/line.js +0 -0
  305. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/diff/sentence.d.ts +0 -0
  306. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/diff/sentence.d.ts.map +0 -0
  307. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/diff/sentence.js +0 -0
  308. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/diff/word.d.ts +0 -0
  309. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/diff/word.d.ts.map +0 -0
  310. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/diff/word.js +0 -0
  311. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/index.d.ts +0 -0
  312. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/index.d.ts.map +0 -0
  313. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/index.js +0 -0
  314. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/package.json +0 -0
  315. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/patch/apply.d.ts +0 -0
  316. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/patch/apply.d.ts.map +0 -0
  317. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/patch/apply.js +0 -0
  318. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/patch/create.d.ts +0 -0
  319. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/patch/create.d.ts.map +0 -0
  320. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/patch/create.js +0 -0
  321. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/patch/line-endings.d.ts +0 -0
  322. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/patch/line-endings.d.ts.map +0 -0
  323. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/patch/line-endings.js +0 -0
  324. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/patch/parse.d.ts +0 -0
  325. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/patch/parse.d.ts.map +0 -0
  326. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/patch/parse.js +0 -0
  327. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/patch/reverse.d.ts +0 -0
  328. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/patch/reverse.d.ts.map +0 -0
  329. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/patch/reverse.js +0 -0
  330. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/types.d.ts +0 -0
  331. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/types.d.ts.map +0 -0
  332. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/types.js +0 -0
  333. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/util/array.d.ts +0 -0
  334. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/util/array.d.ts.map +0 -0
  335. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/util/array.js +0 -0
  336. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/util/distance-iterator.d.ts +0 -0
  337. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/util/distance-iterator.d.ts.map +0 -0
  338. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/util/distance-iterator.js +0 -0
  339. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/util/params.d.ts +0 -0
  340. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/util/params.d.ts.map +0 -0
  341. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/util/params.js +0 -0
  342. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/util/string.d.ts +0 -0
  343. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/util/string.d.ts.map +0 -0
  344. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/libesm/util/string.js +0 -0
  345. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/package.json +0 -0
  346. /package/node_modules/{diff → @pierre/diffs/node_modules/diff}/release-notes.md +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-view-image",
3
- "version": "0.3.7",
3
+ "version": "0.3.8",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -18,18 +18,18 @@
18
18
  "pi": {
19
19
  "extensions": [
20
20
  "./src/extension.ts",
21
- "./node_modules/pi-libtui/src/extension.ts"
21
+ "./node_modules/@luan.sh/pi-libtui/src/extension.ts"
22
22
  ],
23
- "image": "https://github.com/luan/agents/releases/download/v0.3.2/pi-view-image.png",
24
- "video": "https://github.com/luan/agents/releases/download/v0.3.2/pi-view-image.mp4"
23
+ "image": "https://pi.luan.sh/media/previews/pi-view-image-3b76f3119bb5.png",
24
+ "video": "https://pi.luan.sh/media/previews/pi-view-image-62df21208d2a.mp4"
25
25
  },
26
26
  "dependencies": {
27
- "@cfcluan/pi-code-mode": "file:../pi-code-mode",
28
- "pi-libtui": "file:../pi-libtui"
27
+ "@luan.sh/pi-code-mode": "file:../pi-code-mode",
28
+ "@luan.sh/pi-libtui": "file:../pi-libtui"
29
29
  },
30
30
  "bundledDependencies": [
31
- "@cfcluan/pi-code-mode",
32
- "pi-libtui"
31
+ "@luan.sh/pi-code-mode",
32
+ "@luan.sh/pi-libtui"
33
33
  ],
34
34
  "peerDependencies": {
35
35
  "@earendil-works/pi-coding-agent": "*",
@@ -43,5 +43,8 @@
43
43
  "scripts": {
44
44
  "typecheck": "tsc --build",
45
45
  "test": "bun test --only-failures test"
46
- }
46
+ },
47
+ "publishAliases": [
48
+ "pi-view-image"
49
+ ]
47
50
  }
@@ -1,5 +1,5 @@
1
1
  import type { AgentToolResult } from "@earendil-works/pi-coding-agent";
2
- import { type CodeModeToolDetails, registerCodeModeFunctionTool } from "@cfcluan/pi-code-mode/sdk";
2
+ import { type CodeModeToolDetails, registerCodeModeFunctionTool } from "@luan.sh/pi-code-mode/sdk";
3
3
  import type { createViewImageTool } from "./tools/view-image/definition.ts";
4
4
  import type { ViewImageContent } from "./tools/view-image/result.ts";
5
5
 
@@ -1,4 +1,4 @@
1
- import type { PillContent, TuiForegroundColor, TuiIconName } from "pi-libtui";
1
+ import type { PillContent, TuiForegroundColor, TuiIconName } from "@luan.sh/pi-libtui";
2
2
 
3
3
  /** Shared visual identity for every view-image entry point. */
4
4
  export const VIEW_IMAGE_ICON = "view-image" satisfies TuiIconName;
package/src/extension.ts CHANGED
@@ -1,6 +1,7 @@
1
- import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
1
+ import { type ExtensionAPI, resizeImage } from "@earendil-works/pi-coding-agent";
2
2
  import { registerViewImageCodeModeAdapter } from "./code-mode-adapter.ts";
3
3
  import { ImageAttachmentStore } from "./core/attachments.ts";
4
+ import { createImageClamp, MAX_IMAGE_DIMENSION } from "./image-limits.ts";
4
5
  import { resolveViewImageBinary } from "./native/binary.ts";
5
6
  import { labelNativeImageAttachments } from "./native-attachments.ts";
6
7
  import { runViewImageBinary } from "./native/view-image.ts";
@@ -11,6 +12,13 @@ import { configureViewImageToolForModel, createViewImageTool } from "./tools/vie
11
12
  export default function viewImageExtension(pi: ExtensionAPI): void {
12
13
  const tool = createViewImageTool();
13
14
  const attachments = new ImageAttachmentStore();
15
+ const clampImages = createImageClamp(async (image) => {
16
+ const resized = await resizeImage(Buffer.from(image.data, "base64"), image.mimeType, {
17
+ maxWidth: MAX_IMAGE_DIMENSION,
18
+ maxHeight: MAX_IMAGE_DIMENSION,
19
+ });
20
+ return resized?.wasResized ? { type: "image", data: resized.data, mimeType: resized.mimeType } : null;
21
+ });
14
22
  let removeImagePasteSession: (() => void) | undefined;
15
23
  pi.registerTool(tool);
16
24
  pi.on("session_start", (_event, context) => {
@@ -26,7 +34,8 @@ export default function viewImageExtension(pi: ExtensionAPI): void {
26
34
  pi.on("input", async (event, context) => {
27
35
  const transformed = await transformPendingImageAttachments(event, attachments, (path) =>
28
36
  resolveViewImageBinary({ onBuild: (message) => context.ui.notify(message, "info") }).then((binary) =>
29
- runViewImageBinary(binary, { path, detail: "original" }, context.cwd),
37
+ // Pasted screenshots are attached at `high` so oversized captures are resized within provider limits.
38
+ runViewImageBinary(binary, { path, detail: "high" }, context.cwd),
30
39
  ),
31
40
  );
32
41
  if (!transformed) return { action: "continue" };
@@ -35,8 +44,10 @@ export default function viewImageExtension(pi: ExtensionAPI): void {
35
44
  }
36
45
  return { action: "transform", text: transformed.text, images: transformed.images };
37
46
  });
38
- pi.on("context", (event) => {
39
- const messages = labelNativeImageAttachments(event.messages);
47
+ pi.on("context", async (event) => {
48
+ const labelled = labelNativeImageAttachments(event.messages);
49
+ const clamped = await clampImages(labelled ?? event.messages);
50
+ const messages = clamped ?? labelled;
40
51
  return messages ? { messages } : undefined;
41
52
  });
42
53
  const disposeCodeModeAdapter = registerViewImageCodeModeAdapter(tool);
@@ -0,0 +1,57 @@
1
+ import type { ContextEvent } from "@earendil-works/pi-coding-agent";
2
+
3
+ type AgentMessage = ContextEvent["messages"][number];
4
+ export type ImageBlock = { type: "image"; data: string; mimeType: string };
5
+
6
+ // Anthropic rejects images over 2000 px on either side once a request carries more than 20 images.
7
+ // Pi's resizeImage defaults to the same cap; keep them aligned if this changes.
8
+ export const MAX_IMAGE_DIMENSION = 2000;
9
+
10
+ /** Returns a smaller block, or null when the image already fits. */
11
+ export type ResizeImage = (image: ImageBlock) => Promise<ImageBlock | null>;
12
+
13
+ const isImageBlock = (block: unknown): block is ImageBlock =>
14
+ typeof block === "object" &&
15
+ block !== null &&
16
+ Reflect.get(block, "type") === "image" &&
17
+ typeof Reflect.get(block, "data") === "string" &&
18
+ typeof Reflect.get(block, "mimeType") === "string";
19
+
20
+ /**
21
+ * Clamps every image block in the context before a request leaves. Attach-time resizing cannot fix
22
+ * images already in history (pasted before the fix, produced by other extensions, or by Pi itself),
23
+ * so this runs at the model boundary. Each distinct image is decoded once and memoized for the session.
24
+ */
25
+ export function createImageClamp(
26
+ resize: ResizeImage,
27
+ ): (messages: readonly AgentMessage[]) => Promise<AgentMessage[] | undefined> {
28
+ const cache = new Map<string, Promise<ImageBlock | null>>();
29
+ const clamp = (image: ImageBlock): Promise<ImageBlock | null> => {
30
+ let pending = cache.get(image.data);
31
+ if (!pending) {
32
+ pending = resize(image).catch(() => null);
33
+ cache.set(image.data, pending);
34
+ }
35
+ return pending;
36
+ };
37
+
38
+ return async (messages) => {
39
+ let changed = false;
40
+ const next = await Promise.all(
41
+ messages.map(async (message) => {
42
+ if (!("content" in message) || !Array.isArray(message.content)) return message;
43
+ const content = await Promise.all(
44
+ message.content.map(async (block: unknown) => {
45
+ if (!isImageBlock(block)) return block;
46
+ const smaller = await clamp(block);
47
+ if (!smaller) return block;
48
+ changed = true;
49
+ return { ...block, data: smaller.data, mimeType: smaller.mimeType };
50
+ }),
51
+ );
52
+ return { ...message, content } as AgentMessage;
53
+ }),
54
+ );
55
+ return changed ? next : undefined;
56
+ };
57
+ }
@@ -1,6 +1,6 @@
1
- import { type EnsureNativeBinaryHooks, ensureNativeBinary, type NativeBinary } from "pi-libtui";
1
+ import { type EnsureNativeBinaryHooks, ensureNativeBinary, type NativeBinary } from "@luan.sh/pi-libtui";
2
2
 
3
- const VIEW_IMAGE: NativeBinary = { crate: "view-image", binaryName: "view_image", env: "PI_VIEW_IMAGE_BIN" };
3
+ const VIEW_IMAGE: NativeBinary = { crate: "view-image", binaryName: "view-image", env: "PI_VIEW_IMAGE_BIN" };
4
4
 
5
5
  export function resolveViewImageBinary(hooks?: EnsureNativeBinaryHooks): Promise<string> {
6
6
  return ensureNativeBinary(VIEW_IMAGE, hooks);
@@ -1,6 +1,6 @@
1
1
  import type { Theme } from "@earendil-works/pi-coding-agent";
2
- import { renderEditorTokenPills } from "pi-libtui";
3
- import { type EditorRegistry, ensureEditorRegistry } from "pi-libtui/editor";
2
+ import { renderEditorTokenPills } from "@luan.sh/pi-libtui";
3
+ import { type EditorRegistry, ensureEditorRegistry } from "@luan.sh/pi-libtui/editor";
4
4
  import type { ImageAttachmentStore } from "../core/attachments.ts";
5
5
  import { pastedImagePath } from "../core/attachments.ts";
6
6
 
@@ -1,6 +1,6 @@
1
1
  import type { AgentToolResult, Theme } from "@earendil-works/pi-coding-agent";
2
- import { ComponentStack, icon } from "pi-libtui";
3
- import { settleToolCallPreview, ToolActivity, toolCallPreview } from "pi-libtui/tool";
2
+ import { ComponentStack, icon } from "@luan.sh/pi-libtui";
3
+ import { settleToolCallPreview, ToolActivity, toolCallPreview } from "@luan.sh/pi-libtui/tool";
4
4
  import { VIEW_IMAGE_ICON, VIEW_IMAGE_ICON_TONE } from "../../core/appearance.ts";
5
5
  import type { ViewImageDetails } from "./result.ts";
6
6
 
@@ -0,0 +1,50 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { createImageClamp, type ImageBlock } from "../src/image-limits.ts";
3
+
4
+ const image = (data: string): ImageBlock => ({ type: "image", data, mimeType: "image/png" });
5
+ const smaller = (block: ImageBlock): ImageBlock => ({
6
+ type: "image",
7
+ data: `small:${block.data}`,
8
+ mimeType: "image/jpeg",
9
+ });
10
+
11
+ describe("image clamp", () => {
12
+ test("replaces oversized images in user and tool-result messages, once per distinct image", async () => {
13
+ const seen: string[] = [];
14
+ const clamp = createImageClamp(async (block) => {
15
+ seen.push(block.data);
16
+ return block.data.startsWith("big") ? smaller(block) : null;
17
+ });
18
+ const messages = [
19
+ { role: "user", content: [{ type: "text", text: "look" }, image("big-1"), image("fits")], timestamp: 1 },
20
+ {
21
+ role: "toolResult",
22
+ toolCallId: "t",
23
+ toolName: "read",
24
+ content: [image("big-1"), image("big-2")],
25
+ isError: false,
26
+ timestamp: 2,
27
+ },
28
+ ] as never[];
29
+
30
+ const first = await clamp(messages);
31
+ expect(first?.map((message) => Reflect.get(message, "content"))).toEqual([
32
+ [{ type: "text", text: "look" }, { type: "image", data: "small:big-1", mimeType: "image/jpeg" }, image("fits")],
33
+ [
34
+ { type: "image", data: "small:big-1", mimeType: "image/jpeg" },
35
+ { type: "image", data: "small:big-2", mimeType: "image/jpeg" },
36
+ ],
37
+ ]);
38
+
39
+ await clamp(messages);
40
+ expect(seen.sort()).toEqual(["big-1", "big-2", "fits"]);
41
+ });
42
+
43
+ test("returns undefined when nothing needs resizing and tolerates resize failures", async () => {
44
+ const clamp = createImageClamp(async () => {
45
+ throw new Error("decoder unavailable");
46
+ });
47
+ const messages = [{ role: "user", content: [image("any")], timestamp: 1 }] as never[];
48
+ expect(await clamp(messages)).toBeUndefined();
49
+ });
50
+ });
@@ -3,14 +3,14 @@ import { mkdtemp, rm, writeFile } from "node:fs/promises";
3
3
  import { tmpdir } from "node:os";
4
4
  import { join } from "node:path";
5
5
  import { CustomEditor, type Theme } from "@earendil-works/pi-coding-agent";
6
- import { getCodeModeToolAdapterRegistry } from "@cfcluan/pi-code-mode/sdk";
7
- import { icon } from "pi-libtui";
6
+ import { getCodeModeToolAdapterRegistry } from "@luan.sh/pi-code-mode/sdk";
7
+ import { icon } from "@luan.sh/pi-libtui";
8
8
  import {
9
9
  EDITOR_PROTOCOL,
10
10
  type EditorPasteHandler,
11
11
  type EditorRegistry,
12
12
  type EditorRenderDecorator,
13
- } from "pi-libtui/editor";
13
+ } from "@luan.sh/pi-libtui/editor";
14
14
  import { codeModeImageResult, registerViewImageCodeModeAdapter } from "../src/code-mode-adapter.ts";
15
15
  import { ImageAttachmentStore, pastedImagePath } from "../src/core/attachments.ts";
16
16
  import { parseViewImageOutput } from "../src/native/view-image.ts";