tmux-ide 2.9.7 → 2.9.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 (34) hide show
  1. package/bin/cli.js +322 -52
  2. package/package.json +2 -2
  3. package/packages/contracts/src/pane-stream.ts +17 -0
  4. package/packages/contracts/src/terminal-graphics.ts +29 -3
  5. package/packages/core/src/kitty-placeholders.ts +29 -11
  6. package/packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/Info.plist +2 -2
  7. package/packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/MacOS/tmux-ide-notifier +0 -0
  8. package/packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/Resources/Assets.car +0 -0
  9. package/packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/_CodeSignature/CodeResources +2 -2
  10. package/packages/daemon/dist/native/tmux/darwin-arm64/manifest.json +6 -2
  11. package/packages/daemon/dist/native/tmux/darwin-arm64/tmux +0 -0
  12. package/packages/daemon/dist/native/tmux/linux-arm64/manifest.json +6 -2
  13. package/packages/daemon/dist/native/tmux/linux-arm64/tmux +0 -0
  14. package/packages/daemon/dist/native/tmux/linux-x64/manifest.json +6 -2
  15. package/packages/daemon/dist/native/tmux/linux-x64/tmux +0 -0
  16. package/packages/daemon/dist/terminal/attachments/native-runtime.js +25 -12
  17. package/packages/daemon/dist/terminal/graphics/kitty-graphics.js +146 -25
  18. package/packages/daemon/dist/terminal/mirror/mirror-service.js +6 -0
  19. package/packages/daemon/dist/terminal/mirror/session-channel.js +45 -2
  20. package/packages/daemon/dist/terminal/pane-stream/pane-stream-websocket.js +109 -7
  21. package/packages/daemon/dist/terminal/session-runtime/registry.js +9 -0
  22. package/packages/daemon/dist/terminal/session-runtime/terminal-replica-interpreter.js +19 -2
  23. package/packages/daemon/dist/terminal/session-runtime/transport-binding.js +4 -0
  24. package/packages/daemon/src/terminal/attachments/native-runtime.ts +28 -13
  25. package/packages/daemon/src/terminal/graphics/__fixtures__/full-frame-client-recorded.ctl +87 -0
  26. package/packages/daemon/src/terminal/graphics/__fixtures__/full-frame-client.ctl +10 -0
  27. package/packages/daemon/src/terminal/graphics/kitty-graphics.ts +143 -28
  28. package/packages/daemon/src/terminal/mirror/mirror-service.ts +11 -0
  29. package/packages/daemon/src/terminal/mirror/session-channel.ts +61 -2
  30. package/packages/daemon/src/terminal/pane-stream/pane-stream-websocket.ts +123 -6
  31. package/packages/daemon/src/terminal/session-runtime/registry.ts +18 -0
  32. package/packages/daemon/src/terminal/session-runtime/terminal-replica-interpreter.ts +18 -2
  33. package/packages/daemon/src/terminal/session-runtime/transport-binding.ts +5 -0
  34. package/packages/daemon-client/src/pane-stream-client.ts +8 -0
package/bin/cli.js CHANGED
@@ -7177,18 +7177,28 @@ var init_causal_cell = __esm({
7177
7177
 
7178
7178
  // packages/contracts/src/terminal-graphics.ts
7179
7179
  import { z as z45 } from "zod";
7180
- var TERMINAL_GRAPHICS_CAPABILITY_VERSION, TERMINAL_GRAPHICS_BLOB_CHUNK_BYTES, TERMINAL_GRAPHICS_MAX_IMAGE_BYTES, TERMINAL_GRAPHICS_MAX_IMAGES, TERMINAL_GRAPHICS_MAX_PLACEMENTS, TERMINAL_GRAPHICS_MAX_REQUEST_DIGESTS, TerminalGraphicsDigestSchemaZ, TerminalGraphicsFormatSchemaZ, Dimension, Cells, CellIndex, TerminalGraphicsImageSchemaZ, TerminalGraphicsPlacementSchemaZ, TerminalGraphicsStateSchemaZ, TerminalGraphicsBlobSchemaZ;
7180
+ var TERMINAL_GRAPHICS_CAPABILITY_VERSION, TERMINAL_GRAPHICS_ZLIB_CAPABILITY_VERSION, TERMINAL_GRAPHICS_CELL_PIXELS_CAPABILITY_VERSION, TERMINAL_GRAPHICS_PRECISE_PIXELS_CAPABILITY_VERSION, TERMINAL_GRAPHICS_BLOB_CHUNK_BYTES, TERMINAL_GRAPHICS_MAX_IMAGE_BYTES, TERMINAL_GRAPHICS_LEGACY_MAX_IMAGE_BYTES, TERMINAL_GRAPHICS_MAX_IMAGES, TERMINAL_GRAPHICS_MAX_PLACEMENTS, TERMINAL_GRAPHICS_MAX_REQUEST_DIGESTS, TerminalGraphicsDigestSchemaZ, TerminalGraphicsFormatSchemaZ, Dimension, Cells, CellIndex, TerminalGraphicsImageSchemaZ, TerminalGraphicsPlacementSchemaZ, TerminalGraphicsStateSchemaZ, TerminalGraphicsBlobSchemaZ;
7181
7181
  var init_terminal_graphics = __esm({
7182
7182
  "packages/contracts/src/terminal-graphics.ts"() {
7183
7183
  "use strict";
7184
7184
  TERMINAL_GRAPHICS_CAPABILITY_VERSION = /* @__PURE__ */ (() => 101)();
7185
+ TERMINAL_GRAPHICS_ZLIB_CAPABILITY_VERSION = /* @__PURE__ */ (() => 102)();
7186
+ TERMINAL_GRAPHICS_CELL_PIXELS_CAPABILITY_VERSION = /* @__PURE__ */ (() => 103)();
7187
+ TERMINAL_GRAPHICS_PRECISE_PIXELS_CAPABILITY_VERSION = /* @__PURE__ */ (() => 104)();
7185
7188
  TERMINAL_GRAPHICS_BLOB_CHUNK_BYTES = /* @__PURE__ */ (() => 512 * 1024)();
7186
- TERMINAL_GRAPHICS_MAX_IMAGE_BYTES = /* @__PURE__ */ (() => 32 * 1024 * 1024)();
7189
+ TERMINAL_GRAPHICS_MAX_IMAGE_BYTES = /* @__PURE__ */ (() => 64 * 1024 * 1024)();
7190
+ TERMINAL_GRAPHICS_LEGACY_MAX_IMAGE_BYTES = /* @__PURE__ */ (() => 32 * 1024 * 1024)();
7187
7191
  TERMINAL_GRAPHICS_MAX_IMAGES = /* @__PURE__ */ (() => 256)();
7188
7192
  TERMINAL_GRAPHICS_MAX_PLACEMENTS = /* @__PURE__ */ (() => 256)();
7189
7193
  TERMINAL_GRAPHICS_MAX_REQUEST_DIGESTS = /* @__PURE__ */ (() => 64)();
7190
7194
  TerminalGraphicsDigestSchemaZ = /* @__PURE__ */ (() => z45.string().regex(/^[0-9a-f]{32}$/u))();
7191
- TerminalGraphicsFormatSchemaZ = /* @__PURE__ */ (() => z45.enum(["png", "rgba", "rgb"]))();
7195
+ TerminalGraphicsFormatSchemaZ = /* @__PURE__ */ (() => z45.enum([
7196
+ "png",
7197
+ "rgba",
7198
+ "rgb",
7199
+ "rgba-zlib",
7200
+ "rgb-zlib"
7201
+ ]))();
7192
7202
  Dimension = /* @__PURE__ */ (() => z45.number().int().min(1).max(1e4))();
7193
7203
  Cells = /* @__PURE__ */ (() => z45.number().int().min(1).max(1e3))();
7194
7204
  CellIndex = /* @__PURE__ */ (() => z45.number().int().min(0).max(1e3))();
@@ -7217,7 +7227,10 @@ var init_terminal_graphics = __esm({
7217
7227
  TerminalGraphicsStateSchemaZ = /* @__PURE__ */ (() => z45.object({
7218
7228
  revision: z45.number().int().nonnegative(),
7219
7229
  images: z45.array(TerminalGraphicsImageSchemaZ).max(TERMINAL_GRAPHICS_MAX_IMAGES),
7220
- placements: z45.array(TerminalGraphicsPlacementSchemaZ).max(TERMINAL_GRAPHICS_MAX_PLACEMENTS)
7230
+ placements: z45.array(TerminalGraphicsPlacementSchemaZ).max(TERMINAL_GRAPHICS_MAX_PLACEMENTS),
7231
+ /** The daemon accepts `terminal-cell-pixels` (only sent to renderers offering 103). */
7232
+ cellPixels: z45.literal(true).optional(),
7233
+ preciseCellPixels: z45.literal(true).optional()
7221
7234
  }).strict())();
7222
7235
  TerminalGraphicsBlobSchemaZ = /* @__PURE__ */ (() => z45.object({
7223
7236
  digest: TerminalGraphicsDigestSchemaZ,
@@ -7405,7 +7418,7 @@ var init_terminal_delivery = __esm({
7405
7418
 
7406
7419
  // packages/contracts/src/pane-stream.ts
7407
7420
  import { z as z47 } from "zod";
7408
- var PANE_STREAM_CLOCK_BOUNDS_CAPABILITY_V1, PaneStreamDiagnosticCapabilitySchemaZ, PANE_STREAM_PROTOCOL_VERSION, PANE_STREAM_ISSUE_PATH, PANE_STREAM_REDEEM_PATH, PANE_STREAM_WEBSOCKET_SUBPROTOCOL, PANE_STREAM_MAX_PANES, PANE_STREAM_MAX_OUTPUT_BYTES, PANE_STREAM_MAX_OUTPUT_BASE64_CHARS, PANE_STREAM_MAX_SEED_BYTES, PANE_STREAM_MAX_SEED_BASE64_CHARS, PANE_STREAM_MAX_HELD_DELTAS, PANE_STREAM_MAX_LAYOUT_PANES, PANE_STREAM_MAX_GRID_CELLS, PANE_STREAM_MAX_INPUT_SEQUENCE, PaneStreamSemanticPaneIdSchemaZ, PaneStreamViewerModeSchemaZ, PaneSetSchemaZ, PaneStreamLeaseRequestSchemaZ, PaneStreamRedemptionTicketSchemaZ, PaneStreamLoopbackWebSocketUrlSchemaZ, PaneStreamIssueDescriptorSchemaZ, PaneStreamIssueErrorSchemaZ, PaneStreamIssueResultSchemaZ, PaneStreamIssueMutationRequestSchemaZ, BoundedIdentitySchemaZ, PaneStreamRedeemFrameSchemaZ, PaneStreamInputFrameMetadataShape, PaneStreamInputFrameSchemaZ, PaneStreamConsumedFrameSchemaZ, PaneStreamTerminalDeliveryAckFrameSchemaZ, PaneStreamTerminalDeliveryNackFrameSchemaZ, PaneStreamTerminalDeliveryVisibilityFrameSchemaZ, PaneStreamSemanticIntentFrameSchemaZ, PaneStreamViewportFrameSchemaZ, PaneStreamAuthorityRequestIdSchemaZ, PaneStreamAuthorityGenerationSchemaZ, PaneStreamPresenceFrameSchemaZ, PaneStreamActivityFrameSchemaZ, PaneStreamAuthorityRequestFrameSchemaZ, PaneStreamAuthorityReleaseFrameSchemaZ, SharedMonotonicMicrosSchemaZ, PaneStreamClockProbeFrameSchemaZ, PaneStreamTerminalGraphicsRequestFrameSchemaZ, PaneStreamClientFrameSchemaZ, Base64SchemaZ, ServerSeqSchemaZ, GridCellSchemaZ, CellCoordinateSchemaZ, PaneStreamReadyFrameSchemaZ, PaneStreamSeedBatchFrameSchemaZ, PaneStreamOutputFrameSchemaZ, PaneStreamCursorFrameSchemaZ, BoundedDisplayNameSchemaZ, PaneDisplayNameSourceSchemaZ, PaneStreamLayoutFrameSchemaZ, PaneStreamLayoutSnapshotV1FrameSchemaZ, PaneStreamLayoutSnapshotV2FrameSchemaZ, PaneStreamLayoutSnapshotFrameSchemaZ, PaneStreamFlowFrameSchemaZ, PaneStreamClosedFrameSchemaZ, PaneStreamInputAckFrameSchemaZ, PaneStreamClockProbeAckFrameSchemaZ, PaneStreamCausalCellProofFrameSchemaZ, PaneStreamCausalCellFailureFrameSchemaZ, PaneStreamTerminalDeliveryReadyFrameSchemaZ, PaneStreamTerminalDeliveryEnvelopeFrameSchemaZ, PaneStreamTerminalDeliveryChunkFrameSchemaZ, PaneStreamTerminalDeliveryFaultFrameSchemaZ, PaneStreamTerminalGraphicsFrameSchemaZ, PaneStreamTerminalGraphicsBlobFrameSchemaZ, PaneStreamSemanticIntentAckFrameSchemaZ, PaneStreamViewportAckFrameSchemaZ, PaneStreamAuthoritySnapshotFrameSchemaZ, PaneStreamAuthorityReceiptFrameSchemaZ, PaneStreamErrorFrameCodeSchemaZ, PaneStreamErrorFrameSchemaZ, PaneStreamServerFrameSchemaZ;
7421
+ var PANE_STREAM_CLOCK_BOUNDS_CAPABILITY_V1, PaneStreamDiagnosticCapabilitySchemaZ, PANE_STREAM_PROTOCOL_VERSION, PANE_STREAM_ISSUE_PATH, PANE_STREAM_REDEEM_PATH, PANE_STREAM_WEBSOCKET_SUBPROTOCOL, PANE_STREAM_MAX_PANES, PANE_STREAM_MAX_OUTPUT_BYTES, PANE_STREAM_MAX_OUTPUT_BASE64_CHARS, PANE_STREAM_MAX_SEED_BYTES, PANE_STREAM_MAX_SEED_BASE64_CHARS, PANE_STREAM_MAX_HELD_DELTAS, PANE_STREAM_MAX_LAYOUT_PANES, PANE_STREAM_MAX_GRID_CELLS, PANE_STREAM_MAX_INPUT_SEQUENCE, PaneStreamSemanticPaneIdSchemaZ, PaneStreamViewerModeSchemaZ, PaneSetSchemaZ, PaneStreamLeaseRequestSchemaZ, PaneStreamRedemptionTicketSchemaZ, PaneStreamLoopbackWebSocketUrlSchemaZ, PaneStreamIssueDescriptorSchemaZ, PaneStreamIssueErrorSchemaZ, PaneStreamIssueResultSchemaZ, PaneStreamIssueMutationRequestSchemaZ, BoundedIdentitySchemaZ, PaneStreamRedeemFrameSchemaZ, PaneStreamInputFrameMetadataShape, PaneStreamInputFrameSchemaZ, PaneStreamConsumedFrameSchemaZ, PaneStreamTerminalDeliveryAckFrameSchemaZ, PaneStreamTerminalDeliveryNackFrameSchemaZ, PaneStreamTerminalDeliveryVisibilityFrameSchemaZ, PaneStreamSemanticIntentFrameSchemaZ, PaneStreamViewportFrameSchemaZ, PaneStreamAuthorityRequestIdSchemaZ, PaneStreamAuthorityGenerationSchemaZ, PaneStreamPresenceFrameSchemaZ, PaneStreamActivityFrameSchemaZ, PaneStreamAuthorityRequestFrameSchemaZ, PaneStreamAuthorityReleaseFrameSchemaZ, SharedMonotonicMicrosSchemaZ, PaneStreamClockProbeFrameSchemaZ, PaneStreamTerminalGraphicsRequestFrameSchemaZ, PaneStreamTerminalCellPixelsFrameSchemaZ, PaneStreamClientFrameSchemaZ, Base64SchemaZ, ServerSeqSchemaZ, GridCellSchemaZ, CellCoordinateSchemaZ, PaneStreamReadyFrameSchemaZ, PaneStreamSeedBatchFrameSchemaZ, PaneStreamOutputFrameSchemaZ, PaneStreamCursorFrameSchemaZ, BoundedDisplayNameSchemaZ, PaneDisplayNameSourceSchemaZ, PaneStreamLayoutFrameSchemaZ, PaneStreamLayoutSnapshotV1FrameSchemaZ, PaneStreamLayoutSnapshotV2FrameSchemaZ, PaneStreamLayoutSnapshotFrameSchemaZ, PaneStreamFlowFrameSchemaZ, PaneStreamClosedFrameSchemaZ, PaneStreamInputAckFrameSchemaZ, PaneStreamClockProbeAckFrameSchemaZ, PaneStreamCausalCellProofFrameSchemaZ, PaneStreamCausalCellFailureFrameSchemaZ, PaneStreamTerminalDeliveryReadyFrameSchemaZ, PaneStreamTerminalDeliveryEnvelopeFrameSchemaZ, PaneStreamTerminalDeliveryChunkFrameSchemaZ, PaneStreamTerminalDeliveryFaultFrameSchemaZ, PaneStreamTerminalGraphicsFrameSchemaZ, PaneStreamTerminalGraphicsBlobFrameSchemaZ, PaneStreamSemanticIntentAckFrameSchemaZ, PaneStreamViewportAckFrameSchemaZ, PaneStreamAuthoritySnapshotFrameSchemaZ, PaneStreamAuthorityReceiptFrameSchemaZ, PaneStreamErrorFrameCodeSchemaZ, PaneStreamErrorFrameSchemaZ, PaneStreamServerFrameSchemaZ;
7409
7422
  var init_pane_stream = __esm({
7410
7423
  "packages/contracts/src/pane-stream.ts"() {
7411
7424
  "use strict";
@@ -7579,6 +7592,15 @@ var init_pane_stream = __esm({
7579
7592
  pane: PaneStreamSemanticPaneIdSchemaZ,
7580
7593
  digests: z47.array(TerminalGraphicsDigestSchemaZ).min(1).max(TERMINAL_GRAPHICS_MAX_REQUEST_DIGESTS)
7581
7594
  }).strict())();
7595
+ PaneStreamTerminalCellPixelsFrameSchemaZ = /* @__PURE__ */ (() => z47.object({
7596
+ type: z47.literal("terminal-cell-pixels"),
7597
+ width: z47.number().int().min(1).max(1024),
7598
+ height: z47.number().int().min(1).max(1024),
7599
+ precise: z47.object({
7600
+ width: z47.number().int().min(1e3).max(1024e3),
7601
+ height: z47.number().int().min(1e3).max(1024e3)
7602
+ }).strict().optional()
7603
+ }).strict())();
7582
7604
  PaneStreamClientFrameSchemaZ = /* @__PURE__ */ (() => z47.union([
7583
7605
  PaneStreamInputFrameSchemaZ,
7584
7606
  PaneStreamConsumedFrameSchemaZ,
@@ -7592,7 +7614,8 @@ var init_pane_stream = __esm({
7592
7614
  PaneStreamAuthorityRequestFrameSchemaZ,
7593
7615
  PaneStreamAuthorityReleaseFrameSchemaZ,
7594
7616
  PaneStreamClockProbeFrameSchemaZ,
7595
- PaneStreamTerminalGraphicsRequestFrameSchemaZ
7617
+ PaneStreamTerminalGraphicsRequestFrameSchemaZ,
7618
+ PaneStreamTerminalCellPixelsFrameSchemaZ
7596
7619
  ]))();
7597
7620
  Base64SchemaZ = (maxChars) => z47.string().max(maxChars).regex(/^[A-Za-z0-9+/]*={0,2}$/u, "payload must be standard base64");
7598
7621
  ServerSeqSchemaZ = /* @__PURE__ */ (() => z47.number().int().positive())();
@@ -12642,7 +12665,7 @@ var require_package = __commonJS({
12642
12665
  "package.json"(exports, module) {
12643
12666
  module.exports = {
12644
12667
  name: "tmux-ide",
12645
- version: "2.9.7",
12668
+ version: "2.9.8",
12646
12669
  description: "The open-source workspace for coding agents: run Claude Code, Codex and other agents in tmux with live status",
12647
12670
  type: "module",
12648
12671
  bin: {
@@ -12747,7 +12770,7 @@ var require_package = __commonJS({
12747
12770
  "test:tui-gallery": "bun test --preload @opentui/solid/preload --preload ./packages/daemon/test-support/opentui-renderer-preload.ts ./scripts/tui-gallery/gallery.test.tsx",
12748
12771
  "typecheck:tui-gallery": "tsc --noEmit -p scripts/tsconfig.tui-gallery.json",
12749
12772
  "test:spark-qualification": "node --import tsx --test scripts/lib/spark-*.test.ts scripts/lib/spark-*.test.mjs",
12750
- "test:installer": "node --test scripts/install.test.mjs",
12773
+ "test:installer": "node --test scripts/install.test.mjs scripts/lib/installer-service-qualification.test.mjs",
12751
12774
  "qualify:styled-ssh": "node scripts/qualify-styled-ssh.mjs"
12752
12775
  },
12753
12776
  keywords: [
@@ -30784,7 +30807,44 @@ var init_session_channel = __esm({
30784
30807
  this.input.flush();
30785
30808
  this.clearWindowViewports();
30786
30809
  this.restoreWindowSizing(this.attachedIdentity?.runtimeSessionId ?? `=${this.opts.session}`);
30787
- this.io.send(`refresh-client -C ${cols}x${rows}`);
30810
+ this.io.send(`refresh-client -C ${cols}x${rows}${this.cellPixelSuffix()}`);
30811
+ this.clientViewport = { cols, rows };
30812
+ }
30813
+ clientViewport = null;
30814
+ cellPixels = null;
30815
+ /** "/WxH" for tmux's refresh-client -C (patched tmux; stock ignores it). */
30816
+ cellPixelSuffix() {
30817
+ if (!this.cellPixels) return "";
30818
+ const { width, height, precise } = this.cellPixels;
30819
+ return `/${width}x${height}` + (precise ? `/${precise.width}x${precise.height}` : "");
30820
+ }
30821
+ /**
30822
+ * The renderer's cell size in device pixels. tmux answers CSI 14t/16t and
30823
+ * sets TIOCGWINSZ pixels from it, so image programs render 1:1 for the
30824
+ * window. Re-applies the current viewport when the size changes.
30825
+ */
30826
+ setCellPixels(width, height, precise) {
30827
+ if (!Number.isSafeInteger(width) || !Number.isSafeInteger(height) || width < 1 || height < 1 || width > 1024 || height > 1024)
30828
+ throw new RangeError("cell pixel size out of range");
30829
+ if (precise && [precise.width, precise.height].some(
30830
+ (value) => !Number.isSafeInteger(value) || value < 1e3 || value > 1024e3
30831
+ ))
30832
+ throw new RangeError("precise cell pixel size out of range");
30833
+ if (this.cellPixels?.width === width && this.cellPixels.height === height && this.cellPixels.precise?.width === precise?.width && this.cellPixels.precise?.height === precise?.height)
30834
+ return;
30835
+ this.cellPixels = { width, height, ...precise ? { precise } : {} };
30836
+ if (!this.geometryParticipating) return;
30837
+ this.input.flush();
30838
+ if (this.fittedWindows.size > 0) {
30839
+ for (const [runtimeId, size] of this.fittedWindows)
30840
+ if (this.windowsByRuntime.has(runtimeId))
30841
+ this.io.send(
30842
+ `refresh-client -C ${runtimeId}:${size.cols}x${size.rows}${this.cellPixelSuffix()}`
30843
+ );
30844
+ } else if (this.clientViewport)
30845
+ this.io.send(
30846
+ `refresh-client -C ${this.clientViewport.cols}x${this.clientViewport.rows}${this.cellPixelSuffix()}`
30847
+ );
30788
30848
  }
30789
30849
  restoreWindowSizing(target) {
30790
30850
  if (!this.geometryParticipating) return;
@@ -30816,7 +30876,7 @@ var init_session_channel = __esm({
30816
30876
  if (previous?.cols === cols && previous.rows === rows) return;
30817
30877
  this.input.flush();
30818
30878
  this.restoreWindowSizing(window2.runtimeId);
30819
- this.io.send(`refresh-client -C ${window2.runtimeId}:${cols}x${rows}`);
30879
+ this.io.send(`refresh-client -C ${window2.runtimeId}:${cols}x${rows}${this.cellPixelSuffix()}`);
30820
30880
  this.fittedWindows.set(window2.runtimeId, { cols, rows });
30821
30881
  }
30822
30882
  /** Must also run on geometry-owner handoff, before the next owner fits. */
@@ -40130,6 +40190,11 @@ var init_mirror_service = __esm({
40130
40190
  this.assertWindowOwnership(session);
40131
40191
  entry.channel.fitWindowViewport(semanticWindowId, cols, rows);
40132
40192
  }
40193
+ setCellPixels(session, width, height, precise) {
40194
+ const entry = this.channels.get(session);
40195
+ if (!entry || entry.retired) return;
40196
+ entry.channel.setCellPixels(width, height, precise);
40197
+ }
40133
40198
  clearWindowViewports(session) {
40134
40199
  const entry = this.channels.get(session);
40135
40200
  if (entry && !entry.retired) entry.channel.clearWindowViewports();
@@ -57836,7 +57901,7 @@ var init_causal_cell_ledger = __esm({
57836
57901
 
57837
57902
  // packages/daemon/src/terminal/graphics/kitty-graphics.ts
57838
57903
  import { createHash as createHash19 } from "node:crypto";
57839
- import { inflateSync } from "node:zlib";
57904
+ import { deflateSync, inflateSync } from "node:zlib";
57840
57905
  function parseKittyCommand(body) {
57841
57906
  if (!body.startsWith("G")) return null;
57842
57907
  const separator = body.indexOf(";");
@@ -57863,7 +57928,11 @@ function pngDimensions(data) {
57863
57928
  const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
57864
57929
  return { width: view.getUint32(16), height: view.getUint32(20) };
57865
57930
  }
57866
- var KITTY_PLACEMENT_OSC, ESC, MAX_COMMAND_BYTES2, PASSTHROUGH_PREFIX, KittyApcScanner, KittyImageBudget, DEFAULT_KITTY_IMAGE_BUDGET, KittyImageStore, MAX_IMAGES_PER_PANE, MAX_IMAGE_SIDE, clampCells;
57931
+ function virtualGrid(placements) {
57932
+ if (!placements || placements.size === 0) return null;
57933
+ return [...placements.values()].at(-1);
57934
+ }
57935
+ var KITTY_PLACEMENT_OSC, ESC, MAX_COMMAND_BYTES2, PASSTHROUGH_PREFIX, KittyApcScanner, KittyImageBudget, DEFAULT_KITTY_IMAGE_BUDGET, KittyImageStore, MAX_IMAGES_PER_PANE, MAX_RAW_IMAGE_BYTES, MAX_IMAGE_SIDE, clampCells;
57867
57936
  var init_kitty_graphics = __esm({
57868
57937
  "packages/daemon/src/terminal/graphics/kitty-graphics.ts"() {
57869
57938
  "use strict";
@@ -58068,6 +58137,7 @@ var init_kitty_graphics = __esm({
58068
58137
  #images = /* @__PURE__ */ new Map();
58069
58138
  #used = /* @__PURE__ */ new Map();
58070
58139
  #cursorPlacements = [];
58140
+ /** `U=1` virtual placements per image, by placement id (0 when unnamed). */
58071
58141
  #virtual = /* @__PURE__ */ new Map();
58072
58142
  #pending = null;
58073
58143
  #nextAnonymous = 2130706432;
@@ -58105,7 +58175,7 @@ var init_kitty_graphics = __esm({
58105
58175
  this.#used.clear();
58106
58176
  this.#bytes = 0;
58107
58177
  }
58108
- /** A capture reseed replaced the grid: tmux holds no record of cursor placements. */
58178
+ /** The coordinate basis changed: tmux holds no record to restore cursor anchors. */
58109
58179
  dropCursorPlacements() {
58110
58180
  if (this.#cursorPlacements.length === 0) return;
58111
58181
  this.#cursorPlacements.length = 0;
@@ -58128,11 +58198,16 @@ var init_kitty_graphics = __esm({
58128
58198
  if (victim === null) return 0;
58129
58199
  return this.#remove(victim);
58130
58200
  }
58131
- #remove(imageId) {
58201
+ #remove(imageId, keepPlacements = false) {
58132
58202
  const image = this.#images.get(imageId);
58133
58203
  if (!image) return 0;
58134
58204
  this.#images.delete(imageId);
58135
58205
  this.#used.delete(imageId);
58206
+ if (keepPlacements) {
58207
+ this.#bytes -= image.data.byteLength;
58208
+ this.#revision += 1;
58209
+ return image.data.byteLength;
58210
+ }
58136
58211
  this.#virtual.delete(imageId);
58137
58212
  this.#bytes -= image.data.byteLength;
58138
58213
  const kept = this.#cursorPlacements.filter((p) => p.imageId !== imageId);
@@ -58163,7 +58238,7 @@ var init_kitty_graphics = __esm({
58163
58238
  return;
58164
58239
  }
58165
58240
  const action = control.get("a") ?? "t";
58166
- if ((action === "t" || action === "T") && more) {
58241
+ if ((action === "t" || action === "T" || action === "f") && more) {
58167
58242
  this.#pending = { control, payload: [command3.payload], bytes: command3.payload.length };
58168
58243
  return;
58169
58244
  }
@@ -58179,16 +58254,15 @@ var init_kitty_graphics = __esm({
58179
58254
  if (imageId === 0) imageId = this.#nextAnonymous++;
58180
58255
  const image2 = this.#decode(imageId, control, payload);
58181
58256
  if (!image2) return;
58182
- this.#remove(imageId);
58257
+ this.#remove(imageId, true);
58183
58258
  this.#images.set(imageId, image2);
58184
58259
  this.#bytes += image2.data.byteLength;
58185
58260
  this.#used.set(imageId, this.#budget.nextTick());
58186
58261
  this.#revision += 1;
58187
- while ((this.#bytes > this.#budget.perPaneBytes || this.#images.size > MAX_IMAGES_PER_PANE) && this.#images.size > 1)
58188
- this.evictOldest();
58189
- this.#budget.enforce();
58262
+ this.#enforceBudget();
58190
58263
  if (action === "t" || !this.#images.has(imageId)) return;
58191
58264
  }
58265
+ if (action === "f") return this.#editFrame(imageId, control, payload);
58192
58266
  if (action !== "T" && action !== "p") return;
58193
58267
  const image = this.#images.get(imageId);
58194
58268
  if (!image) return;
@@ -58197,7 +58271,20 @@ var init_kitty_graphics = __esm({
58197
58271
  const rows = clampCells(int(control, "r") || Math.ceil(image.height / this.#cellHeight));
58198
58272
  const placementId = int(control, "p");
58199
58273
  if (control.get("U") === "1") {
58200
- this.#virtual.set(imageId, { columns, rows });
58274
+ const placements = this.#virtual.get(imageId) ?? /* @__PURE__ */ new Map();
58275
+ placements.set(placementId, { columns, rows });
58276
+ this.#virtual.set(imageId, placements);
58277
+ let count = 0;
58278
+ for (const entries of this.#virtual.values()) count += entries.size;
58279
+ for (const [id2, entries] of this.#virtual) {
58280
+ for (const placement of entries.keys()) {
58281
+ if (count <= TERMINAL_GRAPHICS_MAX_PLACEMENTS) break;
58282
+ entries.delete(placement);
58283
+ count -= 1;
58284
+ }
58285
+ if (entries.size === 0) this.#virtual.delete(id2);
58286
+ if (count <= TERMINAL_GRAPHICS_MAX_PLACEMENTS) break;
58287
+ }
58201
58288
  } else if (cursor2) {
58202
58289
  const existing = this.#cursorPlacements.findIndex(
58203
58290
  (p) => p.imageId === imageId && placementId !== 0 && p.placementId === placementId
@@ -58219,7 +58306,10 @@ var init_kitty_graphics = __esm({
58219
58306
  }
58220
58307
  #decode(imageId, control, payload) {
58221
58308
  let data = Buffer.from(payload, "base64");
58222
- if (control.get("o") === "z") {
58309
+ const f = int(control, "f", 32);
58310
+ const zlib = control.get("o") === "z";
58311
+ const keepCompressed = zlib && (f === 32 || f === 24);
58312
+ if (zlib && !keepCompressed) {
58223
58313
  try {
58224
58314
  data = inflateSync(data, { maxOutputLength: TERMINAL_GRAPHICS_MAX_IMAGE_BYTES });
58225
58315
  } catch {
@@ -58227,7 +58317,6 @@ var init_kitty_graphics = __esm({
58227
58317
  }
58228
58318
  }
58229
58319
  if (data.byteLength === 0 || data.byteLength > TERMINAL_GRAPHICS_MAX_IMAGE_BYTES) return null;
58230
- const f = int(control, "f", 32);
58231
58320
  let format;
58232
58321
  let width;
58233
58322
  let height;
@@ -58239,33 +58328,100 @@ var init_kitty_graphics = __esm({
58239
58328
  } else if (f === 32 || f === 24) {
58240
58329
  width = int(control, "s");
58241
58330
  height = int(control, "v");
58242
- format = f === 32 ? "rgba" : "rgb";
58243
- if (!width || !height || data.length !== width * height * (f === 32 ? 4 : 3)) return null;
58331
+ const bytes = width * height * (f === 32 ? 4 : 3);
58332
+ if (!width || !height || bytes > MAX_RAW_IMAGE_BYTES) return null;
58333
+ if (keepCompressed) format = f === 32 ? "rgba-zlib" : "rgb-zlib";
58334
+ else {
58335
+ format = f === 32 ? "rgba" : "rgb";
58336
+ if (data.length !== bytes) return null;
58337
+ }
58244
58338
  } else return null;
58245
58339
  if (width < 1 || height < 1 || width > MAX_IMAGE_SIDE || height > MAX_IMAGE_SIDE) return null;
58246
58340
  const digest3 = createHash19("sha256").update(data).digest("hex").slice(0, 32);
58247
58341
  return { imageId, format, width, height, data, digest: digest3 };
58248
58342
  }
58343
+ /**
58344
+ * `a=f` edits of the root frame (`r=1`): RGBA/RGB rectangles written at
58345
+ * `x,y`, replacing (`X=1`) or alpha-blending the existing pixels. New
58346
+ * animation frames, `c` base frames and PNG data are not modelled.
58347
+ */
58348
+ #editFrame(imageId, control, payload) {
58349
+ const image = this.#images.get(imageId);
58350
+ if (!image || int(control, "r") !== 1 || (control.get("t") ?? "d") !== "d") return;
58351
+ const source = image.format === "rgba" || image.format === "rgba-zlib" ? 4 : 3;
58352
+ if (image.format === "png") return;
58353
+ let pixels;
58354
+ let patch = Buffer.from(payload, "base64");
58355
+ try {
58356
+ pixels = image.format === "rgba-zlib" || image.format === "rgb-zlib" ? inflateSync(image.data, { maxOutputLength: MAX_RAW_IMAGE_BYTES }) : Uint8Array.from(image.data);
58357
+ if (control.get("o") === "z")
58358
+ patch = inflateSync(patch, { maxOutputLength: MAX_RAW_IMAGE_BYTES });
58359
+ } catch {
58360
+ return;
58361
+ }
58362
+ const f = int(control, "f", 32);
58363
+ const depth = f === 24 ? 3 : 4;
58364
+ const width = int(control, "s") || image.width;
58365
+ const height = int(control, "v") || image.height;
58366
+ const x0 = int(control, "x");
58367
+ const y0 = int(control, "y");
58368
+ if (f !== 32 && f !== 24 || patch.length !== width * height * depth) return;
58369
+ if (pixels.length !== image.width * image.height * source) return;
58370
+ const replace = control.get("X") === "1";
58371
+ for (let row = 0; row < height && y0 + row < image.height; row += 1)
58372
+ for (let col = 0; col < width && x0 + col < image.width; col += 1) {
58373
+ const from = (row * width + col) * depth;
58374
+ const to = ((y0 + row) * image.width + x0 + col) * source;
58375
+ const alpha = depth === 4 && !replace ? patch[from + 3] / 255 : 1;
58376
+ for (let channel = 0; channel < 3; channel += 1)
58377
+ pixels[to + channel] = Math.round(
58378
+ patch[from + channel] * alpha + pixels[to + channel] * (1 - alpha)
58379
+ );
58380
+ if (source === 4)
58381
+ pixels[to + 3] = depth === 4 && replace ? patch[from + 3] : Math.round(255 * alpha + pixels[to + 3] * (1 - alpha));
58382
+ }
58383
+ const data = deflateSync(pixels, { level: 1 });
58384
+ const format = source === 4 ? "rgba-zlib" : "rgb-zlib";
58385
+ this.#remove(imageId, true);
58386
+ this.#images.set(imageId, {
58387
+ ...image,
58388
+ format,
58389
+ data,
58390
+ digest: createHash19("sha256").update(data).digest("hex").slice(0, 32)
58391
+ });
58392
+ this.#bytes += data.byteLength;
58393
+ this.#used.set(imageId, this.#budget.nextTick());
58394
+ this.#revision += 1;
58395
+ this.#enforceBudget();
58396
+ }
58397
+ #enforceBudget() {
58398
+ while ((this.#bytes > this.#budget.perPaneBytes || this.#images.size > MAX_IMAGES_PER_PANE) && this.#images.size > 0)
58399
+ this.evictOldest();
58400
+ this.#budget.enforce();
58401
+ }
58249
58402
  #delete(control) {
58250
58403
  const what = control.get("d") ?? "a";
58251
58404
  const id2 = int(control, "i");
58252
58405
  const all = what === "a" || what === "A";
58253
58406
  const byId = (what === "i" || what === "I") && id2 !== 0;
58254
58407
  if (!all && !byId) return;
58255
- const keep = (imageId) => !all && imageId !== id2;
58256
- const kept = this.#cursorPlacements.filter((p) => keep(p.imageId));
58408
+ const placementId = control.has("p") ? int(control, "p") : null;
58409
+ const doomed = (imageId, placement) => all || imageId === id2 && (placementId === null || placement === placementId);
58410
+ const kept = this.#cursorPlacements.filter((p) => !doomed(p.imageId, p.placementId));
58257
58411
  if (kept.length !== this.#cursorPlacements.length) {
58258
58412
  this.#cursorPlacements.length = 0;
58259
58413
  this.#cursorPlacements.push(...kept);
58260
58414
  this.#revision += 1;
58261
58415
  }
58262
- for (const key2 of [...this.#virtual.keys()])
58263
- if (!keep(key2)) {
58264
- this.#virtual.delete(key2);
58265
- this.#revision += 1;
58266
- }
58416
+ for (const [imageId, placements] of [...this.#virtual])
58417
+ for (const placement of [...placements.keys()])
58418
+ if (doomed(imageId, placement)) {
58419
+ placements.delete(placement);
58420
+ if (placements.size === 0) this.#virtual.delete(imageId);
58421
+ this.#revision += 1;
58422
+ }
58267
58423
  if (what === "A") for (const key2 of [...this.#images.keys()]) this.#remove(key2);
58268
- if (what === "I") this.#remove(id2);
58424
+ if (what === "I" && placementId === null) this.#remove(id2);
58269
58425
  }
58270
58426
  /**
58271
58427
  * The pane's graphics state for renderers: the image registry (with each
@@ -58280,7 +58436,7 @@ var init_kitty_graphics = __esm({
58280
58436
  width: image.width,
58281
58437
  height: image.height,
58282
58438
  bytes: image.data.byteLength,
58283
- placeholder: this.#virtual.get(image.imageId) ?? null
58439
+ placeholder: virtualGrid(this.#virtual.get(image.imageId))
58284
58440
  }));
58285
58441
  const placements = [];
58286
58442
  for (const placement of this.#cursorPlacements) {
@@ -58308,6 +58464,7 @@ var init_kitty_graphics = __esm({
58308
58464
  }
58309
58465
  };
58310
58466
  MAX_IMAGES_PER_PANE = TERMINAL_GRAPHICS_MAX_IMAGES;
58467
+ MAX_RAW_IMAGE_BYTES = 64 * 1024 * 1024;
58311
58468
  MAX_IMAGE_SIDE = 1e4;
58312
58469
  clampCells = (cells) => Math.max(1, Math.min(1e3, cells));
58313
58470
  }
@@ -58579,7 +58736,8 @@ var init_terminal_replica_interpreter = __esm({
58579
58736
  const previous = this.#backend;
58580
58737
  this.#backend = replacement;
58581
58738
  this.#attachKitty(replacement);
58582
- this.#kitty.dropCursorPlacements();
58739
+ const sameGraphicsBasis = operation.bootstrap === "painted-capture" && previous.cols === replacement.cols && previous.rows === replacement.rows && previous.graphicsViewportTop?.() !== void 0 && previous.graphicsViewportTop?.() === replacement.graphicsViewportTop?.() && previous.modes().alternateScreen === replacement.modes().alternateScreen;
58740
+ if (!sameGraphicsBasis) this.#kitty.dropCursorPlacements();
58583
58741
  this.#nativeReseedRequested = false;
58584
58742
  this.#scrollback = scrollback;
58585
58743
  this.#bootstrap = {
@@ -58611,6 +58769,8 @@ var init_terminal_replica_interpreter = __esm({
58611
58769
  return;
58612
58770
  }
58613
58771
  if (operation.type === "resize") {
58772
+ if (operation.cols !== this.#backend.cols || operation.rows !== this.#backend.rows)
58773
+ this.#kitty.dropCursorPlacements();
58614
58774
  this.#causalCell?.fail("geometry-drift");
58615
58775
  if (this.#backend.modes().synchronizedOutput) {
58616
58776
  this.#backend.resize(operation.cols, operation.rows);
@@ -58655,6 +58815,7 @@ var init_terminal_replica_interpreter = __esm({
58655
58815
  const scanned = this.#kittyScanner.scan(data);
58656
58816
  for (const command3 of scanned.commands) this.#kittyPending.set(command3.marker, command3);
58657
58817
  const parseStarted = this.#observability.enabled ? this.#observability.nowMicros() : 0;
58818
+ if (scanned.forward.byteLength === 0) return;
58658
58819
  await this.#writeToBackend(this.#backend, scanned.forward);
58659
58820
  if (this.#observability.enabled)
58660
58821
  this.#observability.recordSpan(
@@ -62791,6 +62952,11 @@ var init_registry2 = __esm({
62791
62952
  );
62792
62953
  }
62793
62954
  }
62955
+ /** Renderer cell size in device pixels; benign, so any connected client may set it. */
62956
+ setCellPixels(clientId, width, height, precise) {
62957
+ this.#assertConnected(clientId);
62958
+ this.#mirror.setCellPixels?.(this.session, width, height, precise);
62959
+ }
62794
62960
  fitViewportWithAuthority(clientId, lease, cols, rows, semanticWindowId) {
62795
62961
  this.assertGeometryAuthority(clientId, lease);
62796
62962
  this.#mirror.setGeometryParticipation(this.session, true);
@@ -63243,6 +63409,10 @@ var init_registry2 = __esm({
63243
63409
  this.#assertOpen();
63244
63410
  this.#runtime.fitViewport(this.clientId, lease, cols, rows, semanticWindowId);
63245
63411
  }
63412
+ setCellPixels(width, height, precise) {
63413
+ this.#assertOpen();
63414
+ this.#runtime.setCellPixels(this.clientId, width, height, precise);
63415
+ }
63246
63416
  fitViewportWithAuthority(lease, cols, rows, semanticWindowId) {
63247
63417
  this.#assertOpen();
63248
63418
  this.#runtime.fitViewportWithAuthority(this.clientId, lease, cols, rows, semanticWindowId);
@@ -63677,6 +63847,10 @@ var init_transport_binding = __esm({
63677
63847
  throw error;
63678
63848
  }
63679
63849
  }
63850
+ setCellPixels(width, height, precise) {
63851
+ this.#assertOpen();
63852
+ this.#shared.consumer.setCellPixels?.(width, height, precise);
63853
+ }
63680
63854
  fitViewport(expectedLease, cols, rows, semanticWindowId) {
63681
63855
  this.#assertOpen();
63682
63856
  if (this.#shared.geometryTransportLeaseIds.at(-1) !== this.#transportLeaseId) {
@@ -68034,12 +68208,6 @@ async function discoverWorkspaceRegistryTerminalInventory(registry, runner, sign
68034
68208
  const argv = ["list-panes", "-s", "-t", identity2.id, "-F", PANE_FORMAT];
68035
68209
  const before = await requiredTmuxResult(runner, argv, signal);
68036
68210
  if (before === null) continue;
68037
- const first = parsePaneSnapshot(before, identity2);
68038
- const panes2 = first.panes;
68039
- const after = await requiredTmuxResult(runner, argv, signal);
68040
- if (after === null) throw new NativeTerminalAttachmentRuntimeError("discovery-failed");
68041
- const second = parsePaneSnapshot(after, identity2);
68042
- const latest = second.panes;
68043
68211
  const proofKeys = [
68044
68212
  "sessionName",
68045
68213
  "sessionId",
@@ -68051,10 +68219,21 @@ async function discoverWorkspaceRegistryTerminalInventory(registry, runner, sign
68051
68219
  "windowStamp",
68052
68220
  "index"
68053
68221
  ];
68054
- if (first.linksProof !== second.linksProof || panes2.length !== latest.length || panes2.some((pane, index) => proofKeys.some((key2) => pane[key2] !== latest[index][key2]))) {
68055
- throw new NativeTerminalAttachmentRuntimeError("discovery-failed");
68056
- }
68057
- bySessionName.set(sessionName, latest);
68222
+ const matches = (first, second) => first.linksProof === second.linksProof && first.panes.length === second.panes.length && first.panes.every(
68223
+ (pane, index) => proofKeys.every((key2) => pane[key2] === second.panes[index][key2])
68224
+ );
68225
+ let previous = parsePaneSnapshot(before, identity2);
68226
+ let stable = null;
68227
+ for (let attempt = 0; attempt < INVENTORY_FENCE_ATTEMPTS && !stable; attempt += 1) {
68228
+ if (attempt > 0) await settleDelay(attempt);
68229
+ const after = await requiredTmuxResult(runner, argv, signal);
68230
+ if (after === null) throw new NativeTerminalAttachmentRuntimeError("discovery-failed");
68231
+ const next = parsePaneSnapshot(after, identity2);
68232
+ if (matches(previous, next)) stable = next;
68233
+ else previous = next;
68234
+ }
68235
+ if (!stable) throw new NativeTerminalAttachmentRuntimeError("discovery-failed");
68236
+ bySessionName.set(sessionName, stable.panes);
68058
68237
  }
68059
68238
  const panes = [];
68060
68239
  for (const workspace of workspaces) {
@@ -68117,7 +68296,7 @@ async function enumerateStartupMarkedViews(executor) {
68117
68296
  function createNativeTerminalAttachmentRuntime(options) {
68118
68297
  return new NativeTerminalAttachmentRuntime(options);
68119
68298
  }
68120
- var MAX_TMUX_OUTPUT_BYTES3, TERMINAL_ATTACHMENT_TMUX_COMMAND_TIMEOUT_MS, STARTUP_ORPHAN_ENUMERATION_ATTEMPTS, MAX_DISCOVERED_WORKSPACES, MAX_DISCOVERED_PANES, MAX_GEOMETRY_CLIENTS, SAFE_SESSION_NAME, SAFE_TERMINAL_VALUE2, SAFE_COLOR_TERMINAL_VALUE, SAFE_LOCALE_VALUE2, INTEGER, VIEW_MISMATCH, SESSION_WIRE_SENTINEL, PANE_WIRE_SENTINEL, WIRE_SEPARATOR, RUNTIME_SESSION_ID, RUNTIME_WINDOW_ID, RUNTIME_PANE_ID2, ERROR_MESSAGES5, NativeTerminalAttachmentRuntimeError, nativeTerminalAttachmentRuntimeConstructions, SESSION_FORMAT2, PANE_FORMAT, NativeTerminalAttachmentGeometryResolver, WorkspaceTerminalInventoryRuntime, NativeTerminalAttachmentRuntime;
68299
+ var MAX_TMUX_OUTPUT_BYTES3, TERMINAL_ATTACHMENT_TMUX_COMMAND_TIMEOUT_MS, STARTUP_ORPHAN_ENUMERATION_ATTEMPTS, MAX_DISCOVERED_WORKSPACES, MAX_DISCOVERED_PANES, MAX_GEOMETRY_CLIENTS, SAFE_SESSION_NAME, SAFE_TERMINAL_VALUE2, SAFE_COLOR_TERMINAL_VALUE, SAFE_LOCALE_VALUE2, INTEGER, VIEW_MISMATCH, SESSION_WIRE_SENTINEL, PANE_WIRE_SENTINEL, WIRE_SEPARATOR, RUNTIME_SESSION_ID, RUNTIME_WINDOW_ID, RUNTIME_PANE_ID2, ERROR_MESSAGES5, NativeTerminalAttachmentRuntimeError, nativeTerminalAttachmentRuntimeConstructions, SESSION_FORMAT2, PANE_FORMAT, INVENTORY_FENCE_ATTEMPTS, settleDelay, NativeTerminalAttachmentGeometryResolver, WorkspaceTerminalInventoryRuntime, NativeTerminalAttachmentRuntime;
68121
68300
  var init_native_runtime = __esm({
68122
68301
  "packages/daemon/src/terminal/attachments/native-runtime.ts"() {
68123
68302
  "use strict";
@@ -68198,6 +68377,8 @@ var init_native_runtime = __esm({
68198
68377
  "#{pane_birth_id}",
68199
68378
  PANE_WIRE_SENTINEL
68200
68379
  ].join(WIRE_SEPARATOR);
68380
+ INVENTORY_FENCE_ATTEMPTS = 4;
68381
+ settleDelay = (attempt) => new Promise((resolve44) => setTimeout(resolve44, 25 * 2 ** (attempt - 1)));
68201
68382
  NativeTerminalAttachmentGeometryResolver = class {
68202
68383
  #catalog;
68203
68384
  #runner;
@@ -69850,6 +70031,7 @@ var init_wire_ledger = __esm({
69850
70031
  });
69851
70032
 
69852
70033
  // packages/daemon/src/terminal/pane-stream/pane-stream-websocket.ts
70034
+ import { inflateSync as inflateSync2 } from "node:zlib";
69853
70035
  import { z as z108 } from "zod";
69854
70036
  function semanticBackendRefusal(error) {
69855
70037
  let candidate = error;
@@ -69907,6 +70089,22 @@ function errorFrameCode(error) {
69907
70089
  }
69908
70090
  return "stream-unavailable";
69909
70091
  }
70092
+ function rawGraphicsState(state) {
70093
+ const legacy = state.images.map(
70094
+ (image) => image.format === "rgba-zlib" || image.format === "rgb-zlib" ? {
70095
+ ...image,
70096
+ format: image.format === "rgba-zlib" ? "rgba" : "rgb",
70097
+ bytes: image.width * image.height * (image.format === "rgba-zlib" ? 4 : 3)
70098
+ } : image
70099
+ );
70100
+ const images = legacy.filter((image) => image.bytes <= TERMINAL_GRAPHICS_LEGACY_MAX_IMAGE_BYTES);
70101
+ const kept = new Set(images.map((image) => image.digest));
70102
+ return {
70103
+ ...state,
70104
+ images,
70105
+ placements: state.placements.filter((placement) => kept.has(placement.digest))
70106
+ };
70107
+ }
69910
70108
  function concatBytes(chunks) {
69911
70109
  if (chunks.length === 0) return new Uint8Array(0);
69912
70110
  if (chunks.length === 1) return chunks[0];
@@ -70623,7 +70821,9 @@ var init_pane_stream_websocket = __esm({
70623
70821
  batch: null,
70624
70822
  graphicsAnnounced: false,
70625
70823
  graphicsQueue: [],
70626
- graphicsSending: false
70824
+ graphicsSending: false,
70825
+ graphicsServed: /* @__PURE__ */ new Map(),
70826
+ graphicsState: null
70627
70827
  });
70628
70828
  }
70629
70829
  }
@@ -71045,15 +71245,59 @@ var init_pane_stream_websocket = __esm({
71045
71245
  #startGraphics(channel) {
71046
71246
  const graphics = channel.delivery?.graphics;
71047
71247
  if (!graphics) return;
71248
+ const zlib = this.#descriptor.terminalDelivery?.protocolVersions.includes(
71249
+ TERMINAL_GRAPHICS_ZLIB_CAPABILITY_VERSION
71250
+ ) === true;
71251
+ channel.graphicsZlib = zlib;
71252
+ const cellPixels = this.#descriptor.terminalDelivery?.protocolVersions.includes(
71253
+ TERMINAL_GRAPHICS_CELL_PIXELS_CAPABILITY_VERSION
71254
+ ) === true;
71255
+ const preciseCellPixels = this.#descriptor.terminalDelivery?.protocolVersions.includes(
71256
+ TERMINAL_GRAPHICS_PRECISE_PIXELS_CAPABILITY_VERSION
71257
+ ) === true;
71258
+ let announced = false;
71048
71259
  graphics.subscribe((state) => {
71260
+ announced = true;
71049
71261
  if (this.#closed || channel.closed) return;
71050
71262
  channel.graphicsAnnounced = true;
71051
- this.#sendFrame(null, { type: "terminal-graphics", pane: channel.semanticPaneId, state });
71263
+ channel.graphicsState = state;
71264
+ const pushed = [];
71265
+ for (const image of state.images) {
71266
+ const served = channel.graphicsServed.get(image.imageId);
71267
+ if (served !== void 0 && served !== image.digest) pushed.push(image.digest);
71268
+ }
71269
+ this.#sendFrame(null, {
71270
+ type: "terminal-graphics",
71271
+ pane: channel.semanticPaneId,
71272
+ state: {
71273
+ ...zlib ? state : rawGraphicsState(state),
71274
+ ...cellPixels ? { cellPixels: true } : {},
71275
+ ...preciseCellPixels ? { preciseCellPixels: true } : {}
71276
+ }
71277
+ });
71278
+ if (pushed.length > 0) this.#queueGraphics(channel, pushed);
71052
71279
  });
71280
+ if (cellPixels && !announced && !this.#closed && !channel.closed) {
71281
+ channel.graphicsAnnounced = true;
71282
+ this.#sendFrame(null, {
71283
+ type: "terminal-graphics",
71284
+ pane: channel.semanticPaneId,
71285
+ state: {
71286
+ revision: 0,
71287
+ images: [],
71288
+ placements: [],
71289
+ cellPixels: true,
71290
+ ...preciseCellPixels ? { preciseCellPixels: true } : {}
71291
+ }
71292
+ });
71293
+ }
71053
71294
  }
71054
71295
  #requestGraphics(pane, digests) {
71055
71296
  const channel = this.#panes.get(pane);
71056
71297
  if (!channel || channel.closed || !channel.graphicsAnnounced) return;
71298
+ this.#queueGraphics(channel, digests);
71299
+ }
71300
+ #queueGraphics(channel, digests) {
71057
71301
  for (const digest3 of digests)
71058
71302
  if (!channel.graphicsQueue.includes(digest3) && channel.graphicsQueue.length < GRAPHICS_MAX_QUEUED_DIGESTS)
71059
71303
  channel.graphicsQueue.push(digest3);
@@ -71069,28 +71313,47 @@ var init_pane_stream_websocket = __esm({
71069
71313
  try {
71070
71314
  while (!this.#closed && !channel.closed && channel.graphicsQueue.length > 0) {
71071
71315
  const digest3 = channel.graphicsQueue.shift();
71072
- const image = channel.delivery?.graphics?.image(digest3);
71073
- if (!image) continue;
71074
- const total = image.data.byteLength;
71316
+ const graphics = channel.delivery?.graphics;
71317
+ const image = graphics?.image(digest3);
71318
+ if (!graphics || !image) continue;
71319
+ for (const entry of channel.graphicsState?.images ?? [])
71320
+ if (entry.digest === digest3) channel.graphicsServed.set(entry.imageId, digest3);
71321
+ const raw = !channel.graphicsZlib && image.format.endsWith("-zlib");
71322
+ let data = image.data;
71323
+ if (raw) {
71324
+ const expected = image.width * image.height * (image.format === "rgba-zlib" ? 4 : 3);
71325
+ if (expected < 1 || expected > TERMINAL_GRAPHICS_LEGACY_MAX_IMAGE_BYTES) continue;
71326
+ try {
71327
+ data = inflateSync2(image.data, { maxOutputLength: expected });
71328
+ } catch {
71329
+ continue;
71330
+ }
71331
+ if (data.byteLength !== expected) continue;
71332
+ }
71333
+ if (!channel.graphicsZlib && data.byteLength > TERMINAL_GRAPHICS_LEGACY_MAX_IMAGE_BYTES)
71334
+ continue;
71335
+ const format = raw ? image.format === "rgba-zlib" ? "rgba" : "rgb" : image.format;
71336
+ const total = data.byteLength;
71075
71337
  for (let offset = 0; offset < total; offset += TERMINAL_GRAPHICS_BLOB_CHUNK_BYTES) {
71076
71338
  while ((this.#socket.bufferedAmount ?? 0) > GRAPHICS_SEND_WINDOW_BYTES) {
71077
71339
  if (this.#closed || channel.closed) return;
71078
71340
  await new Promise((resolve44) => setTimeout(resolve44, 5));
71079
71341
  }
71080
71342
  if (this.#closed || channel.closed) return;
71343
+ if (offset > 0 && graphics.image(digest3) !== image) break;
71081
71344
  const end = Math.min(total, offset + TERMINAL_GRAPHICS_BLOB_CHUNK_BYTES);
71082
71345
  this.#sendFrame(null, {
71083
71346
  type: "terminal-graphics-blob",
71084
71347
  pane: channel.semanticPaneId,
71085
71348
  blob: {
71086
71349
  digest: digest3,
71087
- format: image.format,
71350
+ format,
71088
71351
  width: image.width,
71089
71352
  height: image.height,
71090
71353
  total,
71091
71354
  offset
71092
71355
  },
71093
- data: Buffer.from(image.data.subarray(offset, end)).toString("base64")
71356
+ data: Buffer.from(data.subarray(offset, end)).toString("base64")
71094
71357
  });
71095
71358
  }
71096
71359
  }
@@ -71577,6 +71840,13 @@ var init_pane_stream_websocket = __esm({
71577
71840
  this.#requestGraphics(frame.pane, frame.digests);
71578
71841
  return;
71579
71842
  }
71843
+ if (frame.type === "terminal-cell-pixels") {
71844
+ try {
71845
+ this.#sessionRuntimeBinding?.setCellPixels?.(frame.width, frame.height, frame.precise);
71846
+ } catch {
71847
+ }
71848
+ return;
71849
+ }
71580
71850
  if (frame.type === "viewport") {
71581
71851
  if (!this.#descriptor.terminalDelivery || this.#descriptor.viewerMode !== "interactive" || frame.seq !== this.#nextViewportSeq || this.#usesExplicitAuthority && !this.#requestedAuthorities.has("geometry")) {
71582
71852
  this.#failProtocol("input-rejected");