tmux-ide 2.9.7 → 2.9.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +323 -55
- package/package.json +2 -2
- package/packages/contracts/src/pane-stream.ts +17 -0
- package/packages/contracts/src/terminal-graphics.ts +29 -3
- package/packages/core/src/kitty-placeholders.ts +29 -11
- package/packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/Info.plist +2 -2
- package/packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/MacOS/tmux-ide-notifier +0 -0
- package/packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/Resources/Assets.car +0 -0
- package/packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/_CodeSignature/CodeResources +2 -2
- package/packages/daemon/dist/native/tmux/darwin-arm64/manifest.json +6 -2
- package/packages/daemon/dist/native/tmux/darwin-arm64/tmux +0 -0
- package/packages/daemon/dist/native/tmux/linux-arm64/manifest.json +6 -2
- package/packages/daemon/dist/native/tmux/linux-arm64/tmux +0 -0
- package/packages/daemon/dist/native/tmux/linux-x64/manifest.json +6 -2
- package/packages/daemon/dist/native/tmux/linux-x64/tmux +0 -0
- package/packages/daemon/dist/terminal/attachments/native-runtime.js +25 -12
- package/packages/daemon/dist/terminal/graphics/kitty-graphics.js +146 -25
- package/packages/daemon/dist/terminal/mirror/mirror-service.js +6 -0
- package/packages/daemon/dist/terminal/mirror/session-channel.js +49 -5
- package/packages/daemon/dist/terminal/pane-stream/pane-stream-websocket.js +109 -7
- package/packages/daemon/dist/terminal/session-runtime/registry.js +9 -1
- package/packages/daemon/dist/terminal/session-runtime/terminal-replica-interpreter.js +19 -2
- package/packages/daemon/dist/terminal/session-runtime/transport-binding.js +4 -0
- package/packages/daemon/src/terminal/attachments/native-runtime.ts +28 -13
- package/packages/daemon/src/terminal/graphics/__fixtures__/full-frame-client-recorded.ctl +87 -0
- package/packages/daemon/src/terminal/graphics/__fixtures__/full-frame-client.ctl +10 -0
- package/packages/daemon/src/terminal/graphics/kitty-graphics.ts +143 -28
- package/packages/daemon/src/terminal/mirror/mirror-service.ts +11 -0
- package/packages/daemon/src/terminal/mirror/session-channel.ts +65 -4
- package/packages/daemon/src/terminal/pane-stream/pane-stream-websocket.ts +123 -6
- package/packages/daemon/src/terminal/session-runtime/registry.ts +18 -1
- package/packages/daemon/src/terminal/session-runtime/terminal-replica-interpreter.ts +18 -2
- package/packages/daemon/src/terminal/session-runtime/transport-binding.ts +5 -0
- 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__ */ (() =>
|
|
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([
|
|
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.
|
|
12668
|
+
version: "2.9.9",
|
|
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,10 +30876,10 @@ 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
|
+
/** Remove scoped overrides when a fresh global viewport supersedes them. */
|
|
30823
30883
|
clearWindowViewports() {
|
|
30824
30884
|
if (!this.fittedWindows.size) return;
|
|
30825
30885
|
this.input.flush();
|
|
@@ -30830,7 +30890,6 @@ var init_session_channel = __esm({
|
|
|
30830
30890
|
}
|
|
30831
30891
|
/** Toggle whether the retained control client participates in tmux sizing. */
|
|
30832
30892
|
setGeometryParticipation(active2) {
|
|
30833
|
-
if (!active2) this.clearWindowViewports();
|
|
30834
30893
|
if (this.geometryParticipating === active2) return;
|
|
30835
30894
|
this.geometryParticipating = active2;
|
|
30836
30895
|
this.input.flush();
|
|
@@ -40130,6 +40189,11 @@ var init_mirror_service = __esm({
|
|
|
40130
40189
|
this.assertWindowOwnership(session);
|
|
40131
40190
|
entry.channel.fitWindowViewport(semanticWindowId, cols, rows);
|
|
40132
40191
|
}
|
|
40192
|
+
setCellPixels(session, width, height, precise) {
|
|
40193
|
+
const entry = this.channels.get(session);
|
|
40194
|
+
if (!entry || entry.retired) return;
|
|
40195
|
+
entry.channel.setCellPixels(width, height, precise);
|
|
40196
|
+
}
|
|
40133
40197
|
clearWindowViewports(session) {
|
|
40134
40198
|
const entry = this.channels.get(session);
|
|
40135
40199
|
if (entry && !entry.retired) entry.channel.clearWindowViewports();
|
|
@@ -57836,7 +57900,7 @@ var init_causal_cell_ledger = __esm({
|
|
|
57836
57900
|
|
|
57837
57901
|
// packages/daemon/src/terminal/graphics/kitty-graphics.ts
|
|
57838
57902
|
import { createHash as createHash19 } from "node:crypto";
|
|
57839
|
-
import { inflateSync } from "node:zlib";
|
|
57903
|
+
import { deflateSync, inflateSync } from "node:zlib";
|
|
57840
57904
|
function parseKittyCommand(body) {
|
|
57841
57905
|
if (!body.startsWith("G")) return null;
|
|
57842
57906
|
const separator = body.indexOf(";");
|
|
@@ -57863,7 +57927,11 @@ function pngDimensions(data) {
|
|
|
57863
57927
|
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
57864
57928
|
return { width: view.getUint32(16), height: view.getUint32(20) };
|
|
57865
57929
|
}
|
|
57866
|
-
|
|
57930
|
+
function virtualGrid(placements) {
|
|
57931
|
+
if (!placements || placements.size === 0) return null;
|
|
57932
|
+
return [...placements.values()].at(-1);
|
|
57933
|
+
}
|
|
57934
|
+
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
57935
|
var init_kitty_graphics = __esm({
|
|
57868
57936
|
"packages/daemon/src/terminal/graphics/kitty-graphics.ts"() {
|
|
57869
57937
|
"use strict";
|
|
@@ -58068,6 +58136,7 @@ var init_kitty_graphics = __esm({
|
|
|
58068
58136
|
#images = /* @__PURE__ */ new Map();
|
|
58069
58137
|
#used = /* @__PURE__ */ new Map();
|
|
58070
58138
|
#cursorPlacements = [];
|
|
58139
|
+
/** `U=1` virtual placements per image, by placement id (0 when unnamed). */
|
|
58071
58140
|
#virtual = /* @__PURE__ */ new Map();
|
|
58072
58141
|
#pending = null;
|
|
58073
58142
|
#nextAnonymous = 2130706432;
|
|
@@ -58105,7 +58174,7 @@ var init_kitty_graphics = __esm({
|
|
|
58105
58174
|
this.#used.clear();
|
|
58106
58175
|
this.#bytes = 0;
|
|
58107
58176
|
}
|
|
58108
|
-
/**
|
|
58177
|
+
/** The coordinate basis changed: tmux holds no record to restore cursor anchors. */
|
|
58109
58178
|
dropCursorPlacements() {
|
|
58110
58179
|
if (this.#cursorPlacements.length === 0) return;
|
|
58111
58180
|
this.#cursorPlacements.length = 0;
|
|
@@ -58128,11 +58197,16 @@ var init_kitty_graphics = __esm({
|
|
|
58128
58197
|
if (victim === null) return 0;
|
|
58129
58198
|
return this.#remove(victim);
|
|
58130
58199
|
}
|
|
58131
|
-
#remove(imageId) {
|
|
58200
|
+
#remove(imageId, keepPlacements = false) {
|
|
58132
58201
|
const image = this.#images.get(imageId);
|
|
58133
58202
|
if (!image) return 0;
|
|
58134
58203
|
this.#images.delete(imageId);
|
|
58135
58204
|
this.#used.delete(imageId);
|
|
58205
|
+
if (keepPlacements) {
|
|
58206
|
+
this.#bytes -= image.data.byteLength;
|
|
58207
|
+
this.#revision += 1;
|
|
58208
|
+
return image.data.byteLength;
|
|
58209
|
+
}
|
|
58136
58210
|
this.#virtual.delete(imageId);
|
|
58137
58211
|
this.#bytes -= image.data.byteLength;
|
|
58138
58212
|
const kept = this.#cursorPlacements.filter((p) => p.imageId !== imageId);
|
|
@@ -58163,7 +58237,7 @@ var init_kitty_graphics = __esm({
|
|
|
58163
58237
|
return;
|
|
58164
58238
|
}
|
|
58165
58239
|
const action = control.get("a") ?? "t";
|
|
58166
|
-
if ((action === "t" || action === "T") && more) {
|
|
58240
|
+
if ((action === "t" || action === "T" || action === "f") && more) {
|
|
58167
58241
|
this.#pending = { control, payload: [command3.payload], bytes: command3.payload.length };
|
|
58168
58242
|
return;
|
|
58169
58243
|
}
|
|
@@ -58179,16 +58253,15 @@ var init_kitty_graphics = __esm({
|
|
|
58179
58253
|
if (imageId === 0) imageId = this.#nextAnonymous++;
|
|
58180
58254
|
const image2 = this.#decode(imageId, control, payload);
|
|
58181
58255
|
if (!image2) return;
|
|
58182
|
-
this.#remove(imageId);
|
|
58256
|
+
this.#remove(imageId, true);
|
|
58183
58257
|
this.#images.set(imageId, image2);
|
|
58184
58258
|
this.#bytes += image2.data.byteLength;
|
|
58185
58259
|
this.#used.set(imageId, this.#budget.nextTick());
|
|
58186
58260
|
this.#revision += 1;
|
|
58187
|
-
|
|
58188
|
-
this.evictOldest();
|
|
58189
|
-
this.#budget.enforce();
|
|
58261
|
+
this.#enforceBudget();
|
|
58190
58262
|
if (action === "t" || !this.#images.has(imageId)) return;
|
|
58191
58263
|
}
|
|
58264
|
+
if (action === "f") return this.#editFrame(imageId, control, payload);
|
|
58192
58265
|
if (action !== "T" && action !== "p") return;
|
|
58193
58266
|
const image = this.#images.get(imageId);
|
|
58194
58267
|
if (!image) return;
|
|
@@ -58197,7 +58270,20 @@ var init_kitty_graphics = __esm({
|
|
|
58197
58270
|
const rows = clampCells(int(control, "r") || Math.ceil(image.height / this.#cellHeight));
|
|
58198
58271
|
const placementId = int(control, "p");
|
|
58199
58272
|
if (control.get("U") === "1") {
|
|
58200
|
-
this.#virtual.
|
|
58273
|
+
const placements = this.#virtual.get(imageId) ?? /* @__PURE__ */ new Map();
|
|
58274
|
+
placements.set(placementId, { columns, rows });
|
|
58275
|
+
this.#virtual.set(imageId, placements);
|
|
58276
|
+
let count = 0;
|
|
58277
|
+
for (const entries of this.#virtual.values()) count += entries.size;
|
|
58278
|
+
for (const [id2, entries] of this.#virtual) {
|
|
58279
|
+
for (const placement of entries.keys()) {
|
|
58280
|
+
if (count <= TERMINAL_GRAPHICS_MAX_PLACEMENTS) break;
|
|
58281
|
+
entries.delete(placement);
|
|
58282
|
+
count -= 1;
|
|
58283
|
+
}
|
|
58284
|
+
if (entries.size === 0) this.#virtual.delete(id2);
|
|
58285
|
+
if (count <= TERMINAL_GRAPHICS_MAX_PLACEMENTS) break;
|
|
58286
|
+
}
|
|
58201
58287
|
} else if (cursor2) {
|
|
58202
58288
|
const existing = this.#cursorPlacements.findIndex(
|
|
58203
58289
|
(p) => p.imageId === imageId && placementId !== 0 && p.placementId === placementId
|
|
@@ -58219,7 +58305,10 @@ var init_kitty_graphics = __esm({
|
|
|
58219
58305
|
}
|
|
58220
58306
|
#decode(imageId, control, payload) {
|
|
58221
58307
|
let data = Buffer.from(payload, "base64");
|
|
58222
|
-
|
|
58308
|
+
const f = int(control, "f", 32);
|
|
58309
|
+
const zlib = control.get("o") === "z";
|
|
58310
|
+
const keepCompressed = zlib && (f === 32 || f === 24);
|
|
58311
|
+
if (zlib && !keepCompressed) {
|
|
58223
58312
|
try {
|
|
58224
58313
|
data = inflateSync(data, { maxOutputLength: TERMINAL_GRAPHICS_MAX_IMAGE_BYTES });
|
|
58225
58314
|
} catch {
|
|
@@ -58227,7 +58316,6 @@ var init_kitty_graphics = __esm({
|
|
|
58227
58316
|
}
|
|
58228
58317
|
}
|
|
58229
58318
|
if (data.byteLength === 0 || data.byteLength > TERMINAL_GRAPHICS_MAX_IMAGE_BYTES) return null;
|
|
58230
|
-
const f = int(control, "f", 32);
|
|
58231
58319
|
let format;
|
|
58232
58320
|
let width;
|
|
58233
58321
|
let height;
|
|
@@ -58239,33 +58327,100 @@ var init_kitty_graphics = __esm({
|
|
|
58239
58327
|
} else if (f === 32 || f === 24) {
|
|
58240
58328
|
width = int(control, "s");
|
|
58241
58329
|
height = int(control, "v");
|
|
58242
|
-
|
|
58243
|
-
if (!width || !height ||
|
|
58330
|
+
const bytes = width * height * (f === 32 ? 4 : 3);
|
|
58331
|
+
if (!width || !height || bytes > MAX_RAW_IMAGE_BYTES) return null;
|
|
58332
|
+
if (keepCompressed) format = f === 32 ? "rgba-zlib" : "rgb-zlib";
|
|
58333
|
+
else {
|
|
58334
|
+
format = f === 32 ? "rgba" : "rgb";
|
|
58335
|
+
if (data.length !== bytes) return null;
|
|
58336
|
+
}
|
|
58244
58337
|
} else return null;
|
|
58245
58338
|
if (width < 1 || height < 1 || width > MAX_IMAGE_SIDE || height > MAX_IMAGE_SIDE) return null;
|
|
58246
58339
|
const digest3 = createHash19("sha256").update(data).digest("hex").slice(0, 32);
|
|
58247
58340
|
return { imageId, format, width, height, data, digest: digest3 };
|
|
58248
58341
|
}
|
|
58342
|
+
/**
|
|
58343
|
+
* `a=f` edits of the root frame (`r=1`): RGBA/RGB rectangles written at
|
|
58344
|
+
* `x,y`, replacing (`X=1`) or alpha-blending the existing pixels. New
|
|
58345
|
+
* animation frames, `c` base frames and PNG data are not modelled.
|
|
58346
|
+
*/
|
|
58347
|
+
#editFrame(imageId, control, payload) {
|
|
58348
|
+
const image = this.#images.get(imageId);
|
|
58349
|
+
if (!image || int(control, "r") !== 1 || (control.get("t") ?? "d") !== "d") return;
|
|
58350
|
+
const source = image.format === "rgba" || image.format === "rgba-zlib" ? 4 : 3;
|
|
58351
|
+
if (image.format === "png") return;
|
|
58352
|
+
let pixels;
|
|
58353
|
+
let patch = Buffer.from(payload, "base64");
|
|
58354
|
+
try {
|
|
58355
|
+
pixels = image.format === "rgba-zlib" || image.format === "rgb-zlib" ? inflateSync(image.data, { maxOutputLength: MAX_RAW_IMAGE_BYTES }) : Uint8Array.from(image.data);
|
|
58356
|
+
if (control.get("o") === "z")
|
|
58357
|
+
patch = inflateSync(patch, { maxOutputLength: MAX_RAW_IMAGE_BYTES });
|
|
58358
|
+
} catch {
|
|
58359
|
+
return;
|
|
58360
|
+
}
|
|
58361
|
+
const f = int(control, "f", 32);
|
|
58362
|
+
const depth = f === 24 ? 3 : 4;
|
|
58363
|
+
const width = int(control, "s") || image.width;
|
|
58364
|
+
const height = int(control, "v") || image.height;
|
|
58365
|
+
const x0 = int(control, "x");
|
|
58366
|
+
const y0 = int(control, "y");
|
|
58367
|
+
if (f !== 32 && f !== 24 || patch.length !== width * height * depth) return;
|
|
58368
|
+
if (pixels.length !== image.width * image.height * source) return;
|
|
58369
|
+
const replace = control.get("X") === "1";
|
|
58370
|
+
for (let row = 0; row < height && y0 + row < image.height; row += 1)
|
|
58371
|
+
for (let col = 0; col < width && x0 + col < image.width; col += 1) {
|
|
58372
|
+
const from = (row * width + col) * depth;
|
|
58373
|
+
const to = ((y0 + row) * image.width + x0 + col) * source;
|
|
58374
|
+
const alpha = depth === 4 && !replace ? patch[from + 3] / 255 : 1;
|
|
58375
|
+
for (let channel = 0; channel < 3; channel += 1)
|
|
58376
|
+
pixels[to + channel] = Math.round(
|
|
58377
|
+
patch[from + channel] * alpha + pixels[to + channel] * (1 - alpha)
|
|
58378
|
+
);
|
|
58379
|
+
if (source === 4)
|
|
58380
|
+
pixels[to + 3] = depth === 4 && replace ? patch[from + 3] : Math.round(255 * alpha + pixels[to + 3] * (1 - alpha));
|
|
58381
|
+
}
|
|
58382
|
+
const data = deflateSync(pixels, { level: 1 });
|
|
58383
|
+
const format = source === 4 ? "rgba-zlib" : "rgb-zlib";
|
|
58384
|
+
this.#remove(imageId, true);
|
|
58385
|
+
this.#images.set(imageId, {
|
|
58386
|
+
...image,
|
|
58387
|
+
format,
|
|
58388
|
+
data,
|
|
58389
|
+
digest: createHash19("sha256").update(data).digest("hex").slice(0, 32)
|
|
58390
|
+
});
|
|
58391
|
+
this.#bytes += data.byteLength;
|
|
58392
|
+
this.#used.set(imageId, this.#budget.nextTick());
|
|
58393
|
+
this.#revision += 1;
|
|
58394
|
+
this.#enforceBudget();
|
|
58395
|
+
}
|
|
58396
|
+
#enforceBudget() {
|
|
58397
|
+
while ((this.#bytes > this.#budget.perPaneBytes || this.#images.size > MAX_IMAGES_PER_PANE) && this.#images.size > 0)
|
|
58398
|
+
this.evictOldest();
|
|
58399
|
+
this.#budget.enforce();
|
|
58400
|
+
}
|
|
58249
58401
|
#delete(control) {
|
|
58250
58402
|
const what = control.get("d") ?? "a";
|
|
58251
58403
|
const id2 = int(control, "i");
|
|
58252
58404
|
const all = what === "a" || what === "A";
|
|
58253
58405
|
const byId = (what === "i" || what === "I") && id2 !== 0;
|
|
58254
58406
|
if (!all && !byId) return;
|
|
58255
|
-
const
|
|
58256
|
-
const
|
|
58407
|
+
const placementId = control.has("p") ? int(control, "p") : null;
|
|
58408
|
+
const doomed = (imageId, placement) => all || imageId === id2 && (placementId === null || placement === placementId);
|
|
58409
|
+
const kept = this.#cursorPlacements.filter((p) => !doomed(p.imageId, p.placementId));
|
|
58257
58410
|
if (kept.length !== this.#cursorPlacements.length) {
|
|
58258
58411
|
this.#cursorPlacements.length = 0;
|
|
58259
58412
|
this.#cursorPlacements.push(...kept);
|
|
58260
58413
|
this.#revision += 1;
|
|
58261
58414
|
}
|
|
58262
|
-
for (const
|
|
58263
|
-
|
|
58264
|
-
|
|
58265
|
-
|
|
58266
|
-
|
|
58415
|
+
for (const [imageId, placements] of [...this.#virtual])
|
|
58416
|
+
for (const placement of [...placements.keys()])
|
|
58417
|
+
if (doomed(imageId, placement)) {
|
|
58418
|
+
placements.delete(placement);
|
|
58419
|
+
if (placements.size === 0) this.#virtual.delete(imageId);
|
|
58420
|
+
this.#revision += 1;
|
|
58421
|
+
}
|
|
58267
58422
|
if (what === "A") for (const key2 of [...this.#images.keys()]) this.#remove(key2);
|
|
58268
|
-
if (what === "I") this.#remove(id2);
|
|
58423
|
+
if (what === "I" && placementId === null) this.#remove(id2);
|
|
58269
58424
|
}
|
|
58270
58425
|
/**
|
|
58271
58426
|
* The pane's graphics state for renderers: the image registry (with each
|
|
@@ -58280,7 +58435,7 @@ var init_kitty_graphics = __esm({
|
|
|
58280
58435
|
width: image.width,
|
|
58281
58436
|
height: image.height,
|
|
58282
58437
|
bytes: image.data.byteLength,
|
|
58283
|
-
placeholder: this.#virtual.get(image.imageId)
|
|
58438
|
+
placeholder: virtualGrid(this.#virtual.get(image.imageId))
|
|
58284
58439
|
}));
|
|
58285
58440
|
const placements = [];
|
|
58286
58441
|
for (const placement of this.#cursorPlacements) {
|
|
@@ -58308,6 +58463,7 @@ var init_kitty_graphics = __esm({
|
|
|
58308
58463
|
}
|
|
58309
58464
|
};
|
|
58310
58465
|
MAX_IMAGES_PER_PANE = TERMINAL_GRAPHICS_MAX_IMAGES;
|
|
58466
|
+
MAX_RAW_IMAGE_BYTES = 64 * 1024 * 1024;
|
|
58311
58467
|
MAX_IMAGE_SIDE = 1e4;
|
|
58312
58468
|
clampCells = (cells) => Math.max(1, Math.min(1e3, cells));
|
|
58313
58469
|
}
|
|
@@ -58579,7 +58735,8 @@ var init_terminal_replica_interpreter = __esm({
|
|
|
58579
58735
|
const previous = this.#backend;
|
|
58580
58736
|
this.#backend = replacement;
|
|
58581
58737
|
this.#attachKitty(replacement);
|
|
58582
|
-
|
|
58738
|
+
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;
|
|
58739
|
+
if (!sameGraphicsBasis) this.#kitty.dropCursorPlacements();
|
|
58583
58740
|
this.#nativeReseedRequested = false;
|
|
58584
58741
|
this.#scrollback = scrollback;
|
|
58585
58742
|
this.#bootstrap = {
|
|
@@ -58611,6 +58768,8 @@ var init_terminal_replica_interpreter = __esm({
|
|
|
58611
58768
|
return;
|
|
58612
58769
|
}
|
|
58613
58770
|
if (operation.type === "resize") {
|
|
58771
|
+
if (operation.cols !== this.#backend.cols || operation.rows !== this.#backend.rows)
|
|
58772
|
+
this.#kitty.dropCursorPlacements();
|
|
58614
58773
|
this.#causalCell?.fail("geometry-drift");
|
|
58615
58774
|
if (this.#backend.modes().synchronizedOutput) {
|
|
58616
58775
|
this.#backend.resize(operation.cols, operation.rows);
|
|
@@ -58655,6 +58814,7 @@ var init_terminal_replica_interpreter = __esm({
|
|
|
58655
58814
|
const scanned = this.#kittyScanner.scan(data);
|
|
58656
58815
|
for (const command3 of scanned.commands) this.#kittyPending.set(command3.marker, command3);
|
|
58657
58816
|
const parseStarted = this.#observability.enabled ? this.#observability.nowMicros() : 0;
|
|
58817
|
+
if (scanned.forward.byteLength === 0) return;
|
|
58658
58818
|
await this.#writeToBackend(this.#backend, scanned.forward);
|
|
58659
58819
|
if (this.#observability.enabled)
|
|
58660
58820
|
this.#observability.recordSpan(
|
|
@@ -62397,7 +62557,6 @@ var init_registry2 = __esm({
|
|
|
62397
62557
|
scheduler,
|
|
62398
62558
|
nativeGeometryHysteresisMs,
|
|
62399
62559
|
onGeometryAuthorityChanged: (clientId) => {
|
|
62400
|
-
this.#mirror.clearWindowViewports(this.session);
|
|
62401
62560
|
this.#mirror.setGeometryParticipation(this.session, clientId !== null);
|
|
62402
62561
|
},
|
|
62403
62562
|
onNativeGeometryYieldExpired: () => this.#publishAuthority()
|
|
@@ -62791,6 +62950,11 @@ var init_registry2 = __esm({
|
|
|
62791
62950
|
);
|
|
62792
62951
|
}
|
|
62793
62952
|
}
|
|
62953
|
+
/** Renderer cell size in device pixels; benign, so any connected client may set it. */
|
|
62954
|
+
setCellPixels(clientId, width, height, precise) {
|
|
62955
|
+
this.#assertConnected(clientId);
|
|
62956
|
+
this.#mirror.setCellPixels?.(this.session, width, height, precise);
|
|
62957
|
+
}
|
|
62794
62958
|
fitViewportWithAuthority(clientId, lease, cols, rows, semanticWindowId) {
|
|
62795
62959
|
this.assertGeometryAuthority(clientId, lease);
|
|
62796
62960
|
this.#mirror.setGeometryParticipation(this.session, true);
|
|
@@ -63243,6 +63407,10 @@ var init_registry2 = __esm({
|
|
|
63243
63407
|
this.#assertOpen();
|
|
63244
63408
|
this.#runtime.fitViewport(this.clientId, lease, cols, rows, semanticWindowId);
|
|
63245
63409
|
}
|
|
63410
|
+
setCellPixels(width, height, precise) {
|
|
63411
|
+
this.#assertOpen();
|
|
63412
|
+
this.#runtime.setCellPixels(this.clientId, width, height, precise);
|
|
63413
|
+
}
|
|
63246
63414
|
fitViewportWithAuthority(lease, cols, rows, semanticWindowId) {
|
|
63247
63415
|
this.#assertOpen();
|
|
63248
63416
|
this.#runtime.fitViewportWithAuthority(this.clientId, lease, cols, rows, semanticWindowId);
|
|
@@ -63677,6 +63845,10 @@ var init_transport_binding = __esm({
|
|
|
63677
63845
|
throw error;
|
|
63678
63846
|
}
|
|
63679
63847
|
}
|
|
63848
|
+
setCellPixels(width, height, precise) {
|
|
63849
|
+
this.#assertOpen();
|
|
63850
|
+
this.#shared.consumer.setCellPixels?.(width, height, precise);
|
|
63851
|
+
}
|
|
63680
63852
|
fitViewport(expectedLease, cols, rows, semanticWindowId) {
|
|
63681
63853
|
this.#assertOpen();
|
|
63682
63854
|
if (this.#shared.geometryTransportLeaseIds.at(-1) !== this.#transportLeaseId) {
|
|
@@ -68034,12 +68206,6 @@ async function discoverWorkspaceRegistryTerminalInventory(registry, runner, sign
|
|
|
68034
68206
|
const argv = ["list-panes", "-s", "-t", identity2.id, "-F", PANE_FORMAT];
|
|
68035
68207
|
const before = await requiredTmuxResult(runner, argv, signal);
|
|
68036
68208
|
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
68209
|
const proofKeys = [
|
|
68044
68210
|
"sessionName",
|
|
68045
68211
|
"sessionId",
|
|
@@ -68051,10 +68217,21 @@ async function discoverWorkspaceRegistryTerminalInventory(registry, runner, sign
|
|
|
68051
68217
|
"windowStamp",
|
|
68052
68218
|
"index"
|
|
68053
68219
|
];
|
|
68054
|
-
|
|
68055
|
-
|
|
68056
|
-
|
|
68057
|
-
|
|
68220
|
+
const matches = (first, second) => first.linksProof === second.linksProof && first.panes.length === second.panes.length && first.panes.every(
|
|
68221
|
+
(pane, index) => proofKeys.every((key2) => pane[key2] === second.panes[index][key2])
|
|
68222
|
+
);
|
|
68223
|
+
let previous = parsePaneSnapshot(before, identity2);
|
|
68224
|
+
let stable = null;
|
|
68225
|
+
for (let attempt = 0; attempt < INVENTORY_FENCE_ATTEMPTS && !stable; attempt += 1) {
|
|
68226
|
+
if (attempt > 0) await settleDelay(attempt);
|
|
68227
|
+
const after = await requiredTmuxResult(runner, argv, signal);
|
|
68228
|
+
if (after === null) throw new NativeTerminalAttachmentRuntimeError("discovery-failed");
|
|
68229
|
+
const next = parsePaneSnapshot(after, identity2);
|
|
68230
|
+
if (matches(previous, next)) stable = next;
|
|
68231
|
+
else previous = next;
|
|
68232
|
+
}
|
|
68233
|
+
if (!stable) throw new NativeTerminalAttachmentRuntimeError("discovery-failed");
|
|
68234
|
+
bySessionName.set(sessionName, stable.panes);
|
|
68058
68235
|
}
|
|
68059
68236
|
const panes = [];
|
|
68060
68237
|
for (const workspace of workspaces) {
|
|
@@ -68117,7 +68294,7 @@ async function enumerateStartupMarkedViews(executor) {
|
|
|
68117
68294
|
function createNativeTerminalAttachmentRuntime(options) {
|
|
68118
68295
|
return new NativeTerminalAttachmentRuntime(options);
|
|
68119
68296
|
}
|
|
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;
|
|
68297
|
+
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
68298
|
var init_native_runtime = __esm({
|
|
68122
68299
|
"packages/daemon/src/terminal/attachments/native-runtime.ts"() {
|
|
68123
68300
|
"use strict";
|
|
@@ -68198,6 +68375,8 @@ var init_native_runtime = __esm({
|
|
|
68198
68375
|
"#{pane_birth_id}",
|
|
68199
68376
|
PANE_WIRE_SENTINEL
|
|
68200
68377
|
].join(WIRE_SEPARATOR);
|
|
68378
|
+
INVENTORY_FENCE_ATTEMPTS = 4;
|
|
68379
|
+
settleDelay = (attempt) => new Promise((resolve44) => setTimeout(resolve44, 25 * 2 ** (attempt - 1)));
|
|
68201
68380
|
NativeTerminalAttachmentGeometryResolver = class {
|
|
68202
68381
|
#catalog;
|
|
68203
68382
|
#runner;
|
|
@@ -69850,6 +70029,7 @@ var init_wire_ledger = __esm({
|
|
|
69850
70029
|
});
|
|
69851
70030
|
|
|
69852
70031
|
// packages/daemon/src/terminal/pane-stream/pane-stream-websocket.ts
|
|
70032
|
+
import { inflateSync as inflateSync2 } from "node:zlib";
|
|
69853
70033
|
import { z as z108 } from "zod";
|
|
69854
70034
|
function semanticBackendRefusal(error) {
|
|
69855
70035
|
let candidate = error;
|
|
@@ -69907,6 +70087,22 @@ function errorFrameCode(error) {
|
|
|
69907
70087
|
}
|
|
69908
70088
|
return "stream-unavailable";
|
|
69909
70089
|
}
|
|
70090
|
+
function rawGraphicsState(state) {
|
|
70091
|
+
const legacy = state.images.map(
|
|
70092
|
+
(image) => image.format === "rgba-zlib" || image.format === "rgb-zlib" ? {
|
|
70093
|
+
...image,
|
|
70094
|
+
format: image.format === "rgba-zlib" ? "rgba" : "rgb",
|
|
70095
|
+
bytes: image.width * image.height * (image.format === "rgba-zlib" ? 4 : 3)
|
|
70096
|
+
} : image
|
|
70097
|
+
);
|
|
70098
|
+
const images = legacy.filter((image) => image.bytes <= TERMINAL_GRAPHICS_LEGACY_MAX_IMAGE_BYTES);
|
|
70099
|
+
const kept = new Set(images.map((image) => image.digest));
|
|
70100
|
+
return {
|
|
70101
|
+
...state,
|
|
70102
|
+
images,
|
|
70103
|
+
placements: state.placements.filter((placement) => kept.has(placement.digest))
|
|
70104
|
+
};
|
|
70105
|
+
}
|
|
69910
70106
|
function concatBytes(chunks) {
|
|
69911
70107
|
if (chunks.length === 0) return new Uint8Array(0);
|
|
69912
70108
|
if (chunks.length === 1) return chunks[0];
|
|
@@ -70623,7 +70819,9 @@ var init_pane_stream_websocket = __esm({
|
|
|
70623
70819
|
batch: null,
|
|
70624
70820
|
graphicsAnnounced: false,
|
|
70625
70821
|
graphicsQueue: [],
|
|
70626
|
-
graphicsSending: false
|
|
70822
|
+
graphicsSending: false,
|
|
70823
|
+
graphicsServed: /* @__PURE__ */ new Map(),
|
|
70824
|
+
graphicsState: null
|
|
70627
70825
|
});
|
|
70628
70826
|
}
|
|
70629
70827
|
}
|
|
@@ -71045,15 +71243,59 @@ var init_pane_stream_websocket = __esm({
|
|
|
71045
71243
|
#startGraphics(channel) {
|
|
71046
71244
|
const graphics = channel.delivery?.graphics;
|
|
71047
71245
|
if (!graphics) return;
|
|
71246
|
+
const zlib = this.#descriptor.terminalDelivery?.protocolVersions.includes(
|
|
71247
|
+
TERMINAL_GRAPHICS_ZLIB_CAPABILITY_VERSION
|
|
71248
|
+
) === true;
|
|
71249
|
+
channel.graphicsZlib = zlib;
|
|
71250
|
+
const cellPixels = this.#descriptor.terminalDelivery?.protocolVersions.includes(
|
|
71251
|
+
TERMINAL_GRAPHICS_CELL_PIXELS_CAPABILITY_VERSION
|
|
71252
|
+
) === true;
|
|
71253
|
+
const preciseCellPixels = this.#descriptor.terminalDelivery?.protocolVersions.includes(
|
|
71254
|
+
TERMINAL_GRAPHICS_PRECISE_PIXELS_CAPABILITY_VERSION
|
|
71255
|
+
) === true;
|
|
71256
|
+
let announced = false;
|
|
71048
71257
|
graphics.subscribe((state) => {
|
|
71258
|
+
announced = true;
|
|
71049
71259
|
if (this.#closed || channel.closed) return;
|
|
71050
71260
|
channel.graphicsAnnounced = true;
|
|
71051
|
-
|
|
71261
|
+
channel.graphicsState = state;
|
|
71262
|
+
const pushed = [];
|
|
71263
|
+
for (const image of state.images) {
|
|
71264
|
+
const served = channel.graphicsServed.get(image.imageId);
|
|
71265
|
+
if (served !== void 0 && served !== image.digest) pushed.push(image.digest);
|
|
71266
|
+
}
|
|
71267
|
+
this.#sendFrame(null, {
|
|
71268
|
+
type: "terminal-graphics",
|
|
71269
|
+
pane: channel.semanticPaneId,
|
|
71270
|
+
state: {
|
|
71271
|
+
...zlib ? state : rawGraphicsState(state),
|
|
71272
|
+
...cellPixels ? { cellPixels: true } : {},
|
|
71273
|
+
...preciseCellPixels ? { preciseCellPixels: true } : {}
|
|
71274
|
+
}
|
|
71275
|
+
});
|
|
71276
|
+
if (pushed.length > 0) this.#queueGraphics(channel, pushed);
|
|
71052
71277
|
});
|
|
71278
|
+
if (cellPixels && !announced && !this.#closed && !channel.closed) {
|
|
71279
|
+
channel.graphicsAnnounced = true;
|
|
71280
|
+
this.#sendFrame(null, {
|
|
71281
|
+
type: "terminal-graphics",
|
|
71282
|
+
pane: channel.semanticPaneId,
|
|
71283
|
+
state: {
|
|
71284
|
+
revision: 0,
|
|
71285
|
+
images: [],
|
|
71286
|
+
placements: [],
|
|
71287
|
+
cellPixels: true,
|
|
71288
|
+
...preciseCellPixels ? { preciseCellPixels: true } : {}
|
|
71289
|
+
}
|
|
71290
|
+
});
|
|
71291
|
+
}
|
|
71053
71292
|
}
|
|
71054
71293
|
#requestGraphics(pane, digests) {
|
|
71055
71294
|
const channel = this.#panes.get(pane);
|
|
71056
71295
|
if (!channel || channel.closed || !channel.graphicsAnnounced) return;
|
|
71296
|
+
this.#queueGraphics(channel, digests);
|
|
71297
|
+
}
|
|
71298
|
+
#queueGraphics(channel, digests) {
|
|
71057
71299
|
for (const digest3 of digests)
|
|
71058
71300
|
if (!channel.graphicsQueue.includes(digest3) && channel.graphicsQueue.length < GRAPHICS_MAX_QUEUED_DIGESTS)
|
|
71059
71301
|
channel.graphicsQueue.push(digest3);
|
|
@@ -71069,28 +71311,47 @@ var init_pane_stream_websocket = __esm({
|
|
|
71069
71311
|
try {
|
|
71070
71312
|
while (!this.#closed && !channel.closed && channel.graphicsQueue.length > 0) {
|
|
71071
71313
|
const digest3 = channel.graphicsQueue.shift();
|
|
71072
|
-
const
|
|
71073
|
-
|
|
71074
|
-
|
|
71314
|
+
const graphics = channel.delivery?.graphics;
|
|
71315
|
+
const image = graphics?.image(digest3);
|
|
71316
|
+
if (!graphics || !image) continue;
|
|
71317
|
+
for (const entry of channel.graphicsState?.images ?? [])
|
|
71318
|
+
if (entry.digest === digest3) channel.graphicsServed.set(entry.imageId, digest3);
|
|
71319
|
+
const raw = !channel.graphicsZlib && image.format.endsWith("-zlib");
|
|
71320
|
+
let data = image.data;
|
|
71321
|
+
if (raw) {
|
|
71322
|
+
const expected = image.width * image.height * (image.format === "rgba-zlib" ? 4 : 3);
|
|
71323
|
+
if (expected < 1 || expected > TERMINAL_GRAPHICS_LEGACY_MAX_IMAGE_BYTES) continue;
|
|
71324
|
+
try {
|
|
71325
|
+
data = inflateSync2(image.data, { maxOutputLength: expected });
|
|
71326
|
+
} catch {
|
|
71327
|
+
continue;
|
|
71328
|
+
}
|
|
71329
|
+
if (data.byteLength !== expected) continue;
|
|
71330
|
+
}
|
|
71331
|
+
if (!channel.graphicsZlib && data.byteLength > TERMINAL_GRAPHICS_LEGACY_MAX_IMAGE_BYTES)
|
|
71332
|
+
continue;
|
|
71333
|
+
const format = raw ? image.format === "rgba-zlib" ? "rgba" : "rgb" : image.format;
|
|
71334
|
+
const total = data.byteLength;
|
|
71075
71335
|
for (let offset = 0; offset < total; offset += TERMINAL_GRAPHICS_BLOB_CHUNK_BYTES) {
|
|
71076
71336
|
while ((this.#socket.bufferedAmount ?? 0) > GRAPHICS_SEND_WINDOW_BYTES) {
|
|
71077
71337
|
if (this.#closed || channel.closed) return;
|
|
71078
71338
|
await new Promise((resolve44) => setTimeout(resolve44, 5));
|
|
71079
71339
|
}
|
|
71080
71340
|
if (this.#closed || channel.closed) return;
|
|
71341
|
+
if (offset > 0 && graphics.image(digest3) !== image) break;
|
|
71081
71342
|
const end = Math.min(total, offset + TERMINAL_GRAPHICS_BLOB_CHUNK_BYTES);
|
|
71082
71343
|
this.#sendFrame(null, {
|
|
71083
71344
|
type: "terminal-graphics-blob",
|
|
71084
71345
|
pane: channel.semanticPaneId,
|
|
71085
71346
|
blob: {
|
|
71086
71347
|
digest: digest3,
|
|
71087
|
-
format
|
|
71348
|
+
format,
|
|
71088
71349
|
width: image.width,
|
|
71089
71350
|
height: image.height,
|
|
71090
71351
|
total,
|
|
71091
71352
|
offset
|
|
71092
71353
|
},
|
|
71093
|
-
data: Buffer.from(
|
|
71354
|
+
data: Buffer.from(data.subarray(offset, end)).toString("base64")
|
|
71094
71355
|
});
|
|
71095
71356
|
}
|
|
71096
71357
|
}
|
|
@@ -71577,6 +71838,13 @@ var init_pane_stream_websocket = __esm({
|
|
|
71577
71838
|
this.#requestGraphics(frame.pane, frame.digests);
|
|
71578
71839
|
return;
|
|
71579
71840
|
}
|
|
71841
|
+
if (frame.type === "terminal-cell-pixels") {
|
|
71842
|
+
try {
|
|
71843
|
+
this.#sessionRuntimeBinding?.setCellPixels?.(frame.width, frame.height, frame.precise);
|
|
71844
|
+
} catch {
|
|
71845
|
+
}
|
|
71846
|
+
return;
|
|
71847
|
+
}
|
|
71580
71848
|
if (frame.type === "viewport") {
|
|
71581
71849
|
if (!this.#descriptor.terminalDelivery || this.#descriptor.viewerMode !== "interactive" || frame.seq !== this.#nextViewportSeq || this.#usesExplicitAuthority && !this.#requestedAuthorities.has("geometry")) {
|
|
71582
71850
|
this.#failProtocol("input-rejected");
|