tmux-ide 2.9.9 → 2.9.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +173 -61
- package/package.json +1 -1
- package/packages/contracts/src/pane-stream.ts +12 -0
- package/packages/core/src/terminal-replica-hash-cache.ts +8 -1
- 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/terminal/mirror/mirror-service.js +12 -2
- package/packages/daemon/dist/terminal/mirror/session-channel.js +46 -23
- package/packages/daemon/dist/terminal/pane-stream/pane-stream-websocket.js +15 -4
- package/packages/daemon/dist/terminal/session-runtime/registry.js +17 -6
- package/packages/daemon/dist/terminal/session-runtime/terminal-replica-interpreter.js +95 -36
- package/packages/daemon/dist/terminal/session-runtime/terminal-replica-owner.js +6 -0
- package/packages/daemon/dist/terminal/session-runtime/transport-binding.js +2 -2
- package/packages/daemon/dist/tui/mirror/runtime/application-generation-starter.js +16 -1
- package/packages/daemon/dist/tui/mirror/runtime/application-machine-agent-navigation.js +13 -0
- package/packages/daemon/dist/tui/mirror/runtime/application-machine-navigation.js +12 -4
- package/packages/daemon/dist/tui/mirror/runtime/application-retained-agent.js +18 -0
- package/packages/daemon/dist/tui/mirror/runtime/application-terminal-interaction-controller.js +62 -2
- package/packages/daemon/dist/tui/mirror/runtime/open-tui-generation-host.js +2 -2
- package/packages/daemon/dist/tui/mirror/runtime/runtime-layout-presentation.js +6 -3
- package/packages/daemon/dist/tui/mirror/runtime/select-terminal-pane.js +7 -2
- package/packages/daemon/dist/tui/mirror/runtime/terminal-selection-waiter.js +36 -0
- package/packages/daemon/src/terminal/mirror/mirror-service.ts +19 -2
- package/packages/daemon/src/terminal/mirror/session-channel.ts +57 -9
- package/packages/daemon/src/terminal/pane-stream/pane-stream-websocket.ts +29 -1
- package/packages/daemon/src/terminal/session-runtime/registry.ts +23 -3
- package/packages/daemon/src/terminal/session-runtime/terminal-replica-interpreter.ts +102 -44
- package/packages/daemon/src/terminal/session-runtime/terminal-replica-owner.ts +7 -0
- package/packages/daemon/src/terminal/session-runtime/transport-binding.ts +3 -0
- package/packages/daemon/src/tui/mirror/open-tui-workspace-runtime-port.ts +2 -0
- package/packages/daemon/src/tui/mirror/runtime/application-generation-starter.ts +17 -1
- package/packages/daemon/src/tui/mirror/runtime/application-machine-agent-navigation.ts +15 -0
- package/packages/daemon/src/tui/mirror/runtime/application-machine-navigation.ts +18 -4
- package/packages/daemon/src/tui/mirror/runtime/application-retained-agent.ts +29 -0
- package/packages/daemon/src/tui/mirror/runtime/application-terminal-interaction-controller.ts +63 -2
- package/packages/daemon/src/tui/mirror/runtime/open-tui-generation-host.ts +2 -2
- package/packages/daemon/src/tui/mirror/runtime/runtime-layout-presentation.ts +7 -4
- package/packages/daemon/src/tui/mirror/runtime/select-terminal-pane.ts +9 -1
- package/packages/daemon/src/tui/mirror/runtime/terminal-selection-waiter.ts +36 -0
- package/packages/daemon-client/src/pane-stream-client.ts +17 -0
package/bin/cli.js
CHANGED
|
@@ -7418,7 +7418,7 @@ var init_terminal_delivery = __esm({
|
|
|
7418
7418
|
|
|
7419
7419
|
// packages/contracts/src/pane-stream.ts
|
|
7420
7420
|
import { z as z47 } from "zod";
|
|
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;
|
|
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, PANE_STREAM_INPUT_LIFETIME_CAPABILITY_VERSION, PaneStreamInputLifetimeSchemaZ, 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;
|
|
7422
7422
|
var init_pane_stream = __esm({
|
|
7423
7423
|
"packages/contracts/src/pane-stream.ts"() {
|
|
7424
7424
|
"use strict";
|
|
@@ -7504,13 +7504,19 @@ var init_pane_stream = __esm({
|
|
|
7504
7504
|
deliveryAcks: z47.boolean().optional(),
|
|
7505
7505
|
diagnosticCapabilities: z47.array(PaneStreamDiagnosticCapabilitySchemaZ).max(2).optional()
|
|
7506
7506
|
}).strict())();
|
|
7507
|
+
PANE_STREAM_INPUT_LIFETIME_CAPABILITY_VERSION = /* @__PURE__ */ (() => 105)();
|
|
7508
|
+
PaneStreamInputLifetimeSchemaZ = /* @__PURE__ */ (() => z47.object({
|
|
7509
|
+
generation: z47.string().min(1).max(256),
|
|
7510
|
+
incarnation: z47.string().min(1).max(256)
|
|
7511
|
+
}).strict())();
|
|
7507
7512
|
PaneStreamInputFrameMetadataShape = /* @__PURE__ */ (() => ({
|
|
7508
7513
|
type: z47.literal("input"),
|
|
7509
7514
|
pane: PaneStreamSemanticPaneIdSchemaZ,
|
|
7510
7515
|
seq: z47.number().int().positive().max(PANE_STREAM_MAX_INPUT_SEQUENCE),
|
|
7511
7516
|
/** Opt-in controlled next-output probe; not a general causal assertion. */
|
|
7512
7517
|
performanceTraceId: z47.uuid().optional(),
|
|
7513
|
-
causalProbe: CausalCellProbeV1SchemaZ.optional()
|
|
7518
|
+
causalProbe: CausalCellProbeV1SchemaZ.optional(),
|
|
7519
|
+
expectedLifetime: PaneStreamInputLifetimeSchemaZ.optional()
|
|
7514
7520
|
}))();
|
|
7515
7521
|
PaneStreamInputFrameSchemaZ = /* @__PURE__ */ (() => z47.discriminatedUnion("kind", [
|
|
7516
7522
|
SessionRuntimeTerminalTextInputSchemaZ.extend(PaneStreamInputFrameMetadataShape),
|
|
@@ -7623,6 +7629,7 @@ var init_pane_stream = __esm({
|
|
|
7623
7629
|
CellCoordinateSchemaZ = /* @__PURE__ */ (() => z47.number().int().min(0).max(PANE_STREAM_MAX_GRID_CELLS))();
|
|
7624
7630
|
PaneStreamReadyFrameSchemaZ = /* @__PURE__ */ (() => z47.object({
|
|
7625
7631
|
type: z47.literal("ready"),
|
|
7632
|
+
inputLifetime: z47.literal(true).optional(),
|
|
7626
7633
|
protocolVersion: z47.literal(PANE_STREAM_PROTOCOL_VERSION),
|
|
7627
7634
|
daemonInstanceId: BoundedIdentitySchemaZ,
|
|
7628
7635
|
requestId: z47.uuid(),
|
|
@@ -12665,7 +12672,7 @@ var require_package = __commonJS({
|
|
|
12665
12672
|
"package.json"(exports, module) {
|
|
12666
12673
|
module.exports = {
|
|
12667
12674
|
name: "tmux-ide",
|
|
12668
|
-
version: "2.9.
|
|
12675
|
+
version: "2.9.11",
|
|
12669
12676
|
description: "The open-source workspace for coding agents: run Claude Code, Codex and other agents in tmux with live status",
|
|
12670
12677
|
type: "module",
|
|
12671
12678
|
bin: {
|
|
@@ -30222,6 +30229,8 @@ var init_session_channel = __esm({
|
|
|
30222
30229
|
fittedWindows = /* @__PURE__ */ new Map();
|
|
30223
30230
|
cancelSync = null;
|
|
30224
30231
|
syncOrdinal = 0;
|
|
30232
|
+
identityJoinOrdinal = 0;
|
|
30233
|
+
trustedInventoryJoinsMissing = false;
|
|
30225
30234
|
completedSyncOrdinal = 0;
|
|
30226
30235
|
lastDisplayNameSyncAtMs = 0;
|
|
30227
30236
|
disposed = false;
|
|
@@ -30445,18 +30454,25 @@ var init_session_channel = __esm({
|
|
|
30445
30454
|
}
|
|
30446
30455
|
/**
|
|
30447
30456
|
* Strict daemon-internal inventory from this channel's current tmux truth.
|
|
30448
|
-
* Unlike
|
|
30449
|
-
*
|
|
30450
|
-
*
|
|
30457
|
+
* Unlike background discovery, this query verifies current native membership
|
|
30458
|
+
* before projecting and rejects incomplete identity. Stream admission may
|
|
30459
|
+
* explicitly join missing pane records after that verification; ordinary
|
|
30460
|
+
* inventory readers retain their existing fail-closed no-join contract.
|
|
30451
30461
|
*/
|
|
30452
|
-
describeTrustedInventory(expectedRuntimeSessionId) {
|
|
30462
|
+
describeTrustedInventory(expectedRuntimeSessionId, joinMissingPanes = false) {
|
|
30453
30463
|
if (this.disposed) {
|
|
30454
30464
|
return Promise.reject(new Error(`mirror session ${this.opts.session} is disposed`));
|
|
30455
30465
|
}
|
|
30456
30466
|
if (this.trustedInventoryFlight) {
|
|
30467
|
+
if (joinMissingPanes && !this.trustedInventoryJoinsMissing && this.trustedInventoryFlightSessionId === expectedRuntimeSessionId)
|
|
30468
|
+
return this.trustedInventoryFlight.then(
|
|
30469
|
+
() => this.describeTrustedInventory(expectedRuntimeSessionId, true),
|
|
30470
|
+
() => this.describeTrustedInventory(expectedRuntimeSessionId, true)
|
|
30471
|
+
);
|
|
30457
30472
|
return this.trustedInventoryFlightSessionId === expectedRuntimeSessionId ? this.trustedInventoryFlight : Promise.reject(new Error(`trusted inventory identity changed for ${this.opts.session}`));
|
|
30458
30473
|
}
|
|
30459
|
-
|
|
30474
|
+
this.trustedInventoryJoinsMissing = joinMissingPanes;
|
|
30475
|
+
const flight = this.refreshTrustedInventory(expectedRuntimeSessionId, 0, joinMissingPanes).catch((error) => {
|
|
30460
30476
|
this.windowLinkAuthority?.invalidate();
|
|
30461
30477
|
this.latestWindowStage = null;
|
|
30462
30478
|
throw error;
|
|
@@ -32455,7 +32471,7 @@ var init_session_channel = __esm({
|
|
|
32455
32471
|
}
|
|
32456
32472
|
return { listed, movedWindowRuntimeIds };
|
|
32457
32473
|
}
|
|
32458
|
-
async refreshTrustedInventory(expectedRuntimeSessionId, attempt = 0) {
|
|
32474
|
+
async refreshTrustedInventory(expectedRuntimeSessionId, attempt = 0, joinMissingPanes = false) {
|
|
32459
32475
|
const authorityOrdinal = this.windowIdentityOrdinal;
|
|
32460
32476
|
const beforeLines = await this.io.request(
|
|
32461
32477
|
`list-panes -s -t "${expectedRuntimeSessionId}" -F "${SESSION_PANE_DESCRIPTOR_FORMAT}"`
|
|
@@ -32523,7 +32539,11 @@ var init_session_channel = __esm({
|
|
|
32523
32539
|
if (windowStage.repairedIdentity || confirmedWindowStage.repairedIdentity || repairedPanes || !coherent || !this.windowStageIdentitiesEqual(windowStage, confirmedWindowStage) || authorityOrdinal !== this.windowIdentityOrdinal) {
|
|
32524
32540
|
if (attempt >= 1)
|
|
32525
32541
|
throw new Error(`trusted inventory for ${this.opts.session} did not settle`);
|
|
32526
|
-
return await this.refreshTrustedInventory(
|
|
32542
|
+
return await this.refreshTrustedInventory(
|
|
32543
|
+
expectedRuntimeSessionId,
|
|
32544
|
+
attempt + 1,
|
|
32545
|
+
joinMissingPanes
|
|
32546
|
+
);
|
|
32527
32547
|
}
|
|
32528
32548
|
if (this.disposed) throw new Error(`mirror session ${this.opts.session} is disposed`);
|
|
32529
32549
|
const activeWindowId = activeWindowIds.values().next().value;
|
|
@@ -32551,7 +32571,22 @@ var init_session_channel = __esm({
|
|
|
32551
32571
|
}
|
|
32552
32572
|
if (confirmedWindowStage.currentWindow !== activeWindowId || confirmedWindowStage.links.length !== descriptors[0].sessionWindowCount || confirmedWindowStage.windows.size !== computedWindowCounts.size || !stagedPaneMembershipExact || stagedPaneCount !== descriptors.length || stagedPaneIds.size !== descriptors.length || [...computedWindowCounts.keys()].some(
|
|
32553
32573
|
(runtimeWindowId) => !confirmedWindowStage.windows.has(runtimeWindowId)
|
|
32554
|
-
)
|
|
32574
|
+
))
|
|
32575
|
+
throw new Error(`trusted inventory for ${this.opts.session} lacks verified identity`);
|
|
32576
|
+
if (joinMissingPanes && descriptors.some(
|
|
32577
|
+
(pane) => this.panesByRuntime.get(pane.runtimePaneId)?.semanticId !== pane.semanticPaneId
|
|
32578
|
+
)) {
|
|
32579
|
+
this.discovery.invalidate();
|
|
32580
|
+
await this.reconcileIdentity(
|
|
32581
|
+
descriptors,
|
|
32582
|
+
runtimePaneIds,
|
|
32583
|
+
() => authorityOrdinal === this.windowIdentityOrdinal,
|
|
32584
|
+
false
|
|
32585
|
+
);
|
|
32586
|
+
}
|
|
32587
|
+
if (this.disposed || authorityOrdinal !== this.windowIdentityOrdinal)
|
|
32588
|
+
throw new Error(`trusted inventory for ${this.opts.session} changed during identity join`);
|
|
32589
|
+
if (descriptors.some((descriptor) => {
|
|
32555
32590
|
const pane = this.panesByRuntime.get(descriptor.runtimePaneId);
|
|
32556
32591
|
const window2 = confirmedWindowStage.windows.get(descriptor.windowId);
|
|
32557
32592
|
return !pane || !window2?.semanticId || descriptor.semanticPaneId !== pane.semanticId || descriptor.semanticWindowId !== window2.semanticId || !WorkspaceIdSchemaZ.safeParse(pane.semanticId).success || !WorkspaceIdSchemaZ.safeParse(window2.semanticId).success;
|
|
@@ -32846,7 +32881,8 @@ var init_session_channel = __esm({
|
|
|
32846
32881
|
}))
|
|
32847
32882
|
};
|
|
32848
32883
|
}
|
|
32849
|
-
async reconcileIdentity(descriptors, listed) {
|
|
32884
|
+
async reconcileIdentity(descriptors, listed, current = () => true, publish = true) {
|
|
32885
|
+
const joinOrdinal = ++this.identityJoinOrdinal;
|
|
32850
32886
|
if (this.disposed) return false;
|
|
32851
32887
|
if (this.opts.hasSharedWindowConflict?.()) {
|
|
32852
32888
|
this.settleFirstJoin();
|
|
@@ -32881,7 +32917,8 @@ var init_session_channel = __esm({
|
|
|
32881
32917
|
)
|
|
32882
32918
|
)
|
|
32883
32919
|
);
|
|
32884
|
-
if (this.disposed)
|
|
32920
|
+
if (this.disposed || !current() || joinOrdinal !== this.identityJoinOrdinal)
|
|
32921
|
+
return plan.stampEffects.length > 0;
|
|
32885
32922
|
const reconciliation = finalizeWorkspaceTmuxReconciliation(plan, outcomes);
|
|
32886
32923
|
const descriptorByRuntime = new Map(descriptors.map((d) => [d.runtimePaneId, d]));
|
|
32887
32924
|
for (const verified of reconciliation.panes) {
|
|
@@ -32968,8 +33005,10 @@ var init_session_channel = __esm({
|
|
|
32968
33005
|
degraded: diagnostic4.degraded
|
|
32969
33006
|
}));
|
|
32970
33007
|
this.degraded = reconciliation.degraded;
|
|
32971
|
-
|
|
32972
|
-
|
|
33008
|
+
if (publish) {
|
|
33009
|
+
for (const runtimeId of this.layoutByWindow.keys()) this.emitLayout(runtimeId);
|
|
33010
|
+
this.emitLayoutAuthority();
|
|
33011
|
+
}
|
|
32973
33012
|
this.settleFirstJoin();
|
|
32974
33013
|
return plan.stampEffects.length > 0;
|
|
32975
33014
|
}
|
|
@@ -39938,11 +39977,20 @@ var init_mirror_service = __esm({
|
|
|
39938
39977
|
this.release(session, entry);
|
|
39939
39978
|
}
|
|
39940
39979
|
}
|
|
39941
|
-
async describeSessionAuthority(session) {
|
|
39980
|
+
async describeSessionAuthority(session, expectedSemanticPaneIds) {
|
|
39942
39981
|
const entry = await this.acquire(session);
|
|
39943
39982
|
try {
|
|
39944
39983
|
const identity2 = await entry.channel.attachedSessionIdentity();
|
|
39945
|
-
|
|
39984
|
+
let description = entry.channel.describe();
|
|
39985
|
+
if (expectedSemanticPaneIds?.some(
|
|
39986
|
+
(id2) => !description.panes.some((pane) => pane.semanticPaneId === id2)
|
|
39987
|
+
)) {
|
|
39988
|
+
await entry.channel.describeTrustedInventory(identity2.runtimeSessionId, true);
|
|
39989
|
+
description = entry.channel.describe();
|
|
39990
|
+
}
|
|
39991
|
+
if (this.disposed || entry.retired || this.channels.get(session) !== entry)
|
|
39992
|
+
throw new Error("Mirror authority retired during description");
|
|
39993
|
+
return { description, runtimeSessionId: identity2.runtimeSessionId };
|
|
39946
39994
|
} finally {
|
|
39947
39995
|
this.release(session, entry);
|
|
39948
39996
|
}
|
|
@@ -58489,7 +58537,7 @@ function projectPlacements(rows, viewportRows, cols) {
|
|
|
58489
58537
|
}
|
|
58490
58538
|
];
|
|
58491
58539
|
}
|
|
58492
|
-
var TerminalReplicaInterpreter;
|
|
58540
|
+
var MAX_INGEST_BATCH_BYTES, TerminalReplicaInterpreter;
|
|
58493
58541
|
var init_terminal_replica_interpreter = __esm({
|
|
58494
58542
|
"packages/daemon/src/terminal/session-runtime/terminal-replica-interpreter.ts"() {
|
|
58495
58543
|
"use strict";
|
|
@@ -58502,6 +58550,7 @@ var init_terminal_replica_interpreter = __esm({
|
|
|
58502
58550
|
init_xterm_terminal_interpreter_backend();
|
|
58503
58551
|
init_causal_cell_ledger();
|
|
58504
58552
|
init_kitty_graphics();
|
|
58553
|
+
MAX_INGEST_BATCH_BYTES = 256 * 1024;
|
|
58505
58554
|
TerminalReplicaInterpreter = class {
|
|
58506
58555
|
#nativeSeedBackingCandidate;
|
|
58507
58556
|
#generation;
|
|
@@ -58529,8 +58578,7 @@ var init_terminal_replica_interpreter = __esm({
|
|
|
58529
58578
|
#needsSeed = true;
|
|
58530
58579
|
#closed = false;
|
|
58531
58580
|
#walkCount = 0;
|
|
58532
|
-
#pendingWrites =
|
|
58533
|
-
#writeFlushScheduled = false;
|
|
58581
|
+
#pendingWrites = null;
|
|
58534
58582
|
#widgetGate = false;
|
|
58535
58583
|
// kitty graphics: images outlive reseeds; the scanner owns split APCs.
|
|
58536
58584
|
#kittyScanner = new KittyApcScanner();
|
|
@@ -58601,15 +58649,22 @@ var init_terminal_replica_interpreter = __esm({
|
|
|
58601
58649
|
if (operation.type === "write") {
|
|
58602
58650
|
const data = operation.data.slice();
|
|
58603
58651
|
const trace = operation.trace ?? null;
|
|
58604
|
-
|
|
58605
|
-
if (this.#pendingWrites.length > 0 && (pendingTrace?.traceId ?? null) !== (trace?.traceId ?? null))
|
|
58652
|
+
if (this.#pendingWrites && (this.#pendingWrites.trace?.traceId ?? null) !== (trace?.traceId ?? null))
|
|
58606
58653
|
this.#flushWrites();
|
|
58654
|
+
const group = this.#pendingWrites ??= {
|
|
58655
|
+
entries: [],
|
|
58656
|
+
bytes: 0,
|
|
58657
|
+
scheduled: false,
|
|
58658
|
+
flushQueued: false,
|
|
58659
|
+
trace
|
|
58660
|
+
};
|
|
58607
58661
|
const promise = new Promise((resolve44, reject) => {
|
|
58608
|
-
|
|
58662
|
+
group.entries.push({ data, offset: 0, resolve: resolve44, reject });
|
|
58663
|
+
group.bytes += data.length;
|
|
58609
58664
|
});
|
|
58610
|
-
if (!
|
|
58611
|
-
|
|
58612
|
-
this.#scheduler.microtask(() => this.#
|
|
58665
|
+
if (!group.scheduled && !group.flushQueued) {
|
|
58666
|
+
group.flushQueued = true;
|
|
58667
|
+
this.#scheduler.microtask(() => this.#scheduleWriteGroup(group));
|
|
58613
58668
|
}
|
|
58614
58669
|
return promise;
|
|
58615
58670
|
}
|
|
@@ -58815,7 +58870,18 @@ var init_terminal_replica_interpreter = __esm({
|
|
|
58815
58870
|
for (const command3 of scanned.commands) this.#kittyPending.set(command3.marker, command3);
|
|
58816
58871
|
const parseStarted = this.#observability.enabled ? this.#observability.nowMicros() : 0;
|
|
58817
58872
|
if (scanned.forward.byteLength === 0) return;
|
|
58818
|
-
|
|
58873
|
+
for (let offset = 0; offset < scanned.forward.length; offset += MAX_INGEST_BATCH_BYTES) {
|
|
58874
|
+
await this.#writeToBackend(
|
|
58875
|
+
this.#backend,
|
|
58876
|
+
scanned.forward.subarray(offset, offset + MAX_INGEST_BATCH_BYTES)
|
|
58877
|
+
);
|
|
58878
|
+
const dirty = this.#backend.dirtyRange();
|
|
58879
|
+
const pending = this.#pendingWriteDirty;
|
|
58880
|
+
this.#pendingWriteDirty = pending === null ? dirty : pending === void 0 || dirty === void 0 ? void 0 : {
|
|
58881
|
+
start: Math.min(pending.start, dirty.start),
|
|
58882
|
+
end: Math.max(pending.end, dirty.end)
|
|
58883
|
+
};
|
|
58884
|
+
}
|
|
58819
58885
|
if (this.#observability.enabled)
|
|
58820
58886
|
this.#observability.recordSpan(
|
|
58821
58887
|
"parse",
|
|
@@ -58824,12 +58890,6 @@ var init_terminal_replica_interpreter = __esm({
|
|
|
58824
58890
|
this.#observability.nowMicros(),
|
|
58825
58891
|
trace
|
|
58826
58892
|
);
|
|
58827
|
-
const dirty = this.#backend.dirtyRange();
|
|
58828
|
-
const pending = this.#pendingWriteDirty;
|
|
58829
|
-
this.#pendingWriteDirty = pending === null ? dirty : pending === void 0 || dirty === void 0 ? void 0 : {
|
|
58830
|
-
start: Math.min(pending.start, dirty.start),
|
|
58831
|
-
end: Math.max(pending.end, dirty.end)
|
|
58832
|
-
};
|
|
58833
58893
|
if (this.#backend.requiresNativeReseed()) {
|
|
58834
58894
|
this.#commit(false);
|
|
58835
58895
|
return;
|
|
@@ -58852,6 +58912,7 @@ var init_terminal_replica_interpreter = __esm({
|
|
|
58852
58912
|
if (this.#syncRecovery || this.#closed) return;
|
|
58853
58913
|
this.#syncRecovery = this.#scheduler.timer(() => {
|
|
58854
58914
|
this.#syncRecovery = null;
|
|
58915
|
+
this.#flushWrites();
|
|
58855
58916
|
const run = this.#tail.then(async () => {
|
|
58856
58917
|
if (this.#closed || !this.#backend.modes().synchronizedOutput) return;
|
|
58857
58918
|
await this.#backend.write("\x1B[?2026l");
|
|
@@ -59093,24 +59154,51 @@ var init_terminal_replica_interpreter = __esm({
|
|
|
59093
59154
|
}
|
|
59094
59155
|
}
|
|
59095
59156
|
}
|
|
59157
|
+
/** Seal the current group at every trace, control and idle barrier. */
|
|
59096
59158
|
#flushWrites() {
|
|
59097
|
-
|
|
59098
|
-
|
|
59099
|
-
|
|
59100
|
-
|
|
59101
|
-
|
|
59102
|
-
|
|
59103
|
-
|
|
59104
|
-
|
|
59105
|
-
|
|
59106
|
-
|
|
59107
|
-
|
|
59108
|
-
|
|
59159
|
+
const group = this.#pendingWrites;
|
|
59160
|
+
this.#pendingWrites = null;
|
|
59161
|
+
if (group) this.#scheduleWriteGroup(group);
|
|
59162
|
+
}
|
|
59163
|
+
#scheduleWriteGroup(group) {
|
|
59164
|
+
if (group.scheduled) return;
|
|
59165
|
+
group.scheduled = true;
|
|
59166
|
+
const run = this.#tail.then(async () => {
|
|
59167
|
+
try {
|
|
59168
|
+
while (group.entries.length > 0) {
|
|
59169
|
+
const length = Math.min(group.bytes, MAX_INGEST_BATCH_BYTES);
|
|
59170
|
+
const data = new Uint8Array(length);
|
|
59171
|
+
const completed = [];
|
|
59172
|
+
let offset = 0;
|
|
59173
|
+
for (const entry of group.entries) {
|
|
59174
|
+
const take = Math.min(entry.data.length - entry.offset, length - offset);
|
|
59175
|
+
data.set(entry.data.subarray(entry.offset, entry.offset + take), offset);
|
|
59176
|
+
offset += take;
|
|
59177
|
+
entry.offset += take;
|
|
59178
|
+
if (entry.offset === entry.data.length) completed.push(entry);
|
|
59179
|
+
else break;
|
|
59180
|
+
if (offset === length && length > 0) break;
|
|
59181
|
+
}
|
|
59182
|
+
group.entries.splice(0, completed.length);
|
|
59183
|
+
group.bytes -= length;
|
|
59184
|
+
try {
|
|
59185
|
+
await this.#write(data, group.trace);
|
|
59186
|
+
} catch (error) {
|
|
59187
|
+
for (const entry of completed) entry.reject(error);
|
|
59188
|
+
throw error;
|
|
59189
|
+
}
|
|
59190
|
+
for (const entry of completed) entry.resolve();
|
|
59191
|
+
}
|
|
59192
|
+
} catch (error) {
|
|
59193
|
+
for (const entry of group.entries) entry.reject(error);
|
|
59194
|
+
group.entries.length = 0;
|
|
59195
|
+
group.bytes = 0;
|
|
59196
|
+
throw error;
|
|
59197
|
+
} finally {
|
|
59198
|
+
if (this.#pendingWrites === group) this.#pendingWrites = null;
|
|
59199
|
+
}
|
|
59200
|
+
});
|
|
59109
59201
|
this.#tail = run.catch(() => void 0);
|
|
59110
|
-
void run.then(
|
|
59111
|
-
() => pending.forEach((entry) => entry.resolve()),
|
|
59112
|
-
(error) => pending.forEach((entry) => entry.reject(error))
|
|
59113
|
-
);
|
|
59114
59202
|
}
|
|
59115
59203
|
#observeMarkerBytes(data) {
|
|
59116
59204
|
if (this.#widgetGate) return;
|
|
@@ -59291,6 +59379,10 @@ var init_terminal_replica_owner = __esm({
|
|
|
59291
59379
|
inputDispatchIncarnation() {
|
|
59292
59380
|
return this.#disposed ? null : this.#publishedIncarnation;
|
|
59293
59381
|
}
|
|
59382
|
+
/** Scalar admission fence; unavailable while canonical replacement is pending. */
|
|
59383
|
+
inputAdmissionIncarnation() {
|
|
59384
|
+
return this.#disposed || this.#reseed || this.#waitingForGeometryCapture ? null : this.#publishedIncarnation;
|
|
59385
|
+
}
|
|
59294
59386
|
qualificationSnapshot() {
|
|
59295
59387
|
const seed = this.#interpreter.currentSeed();
|
|
59296
59388
|
return Object.freeze({
|
|
@@ -62271,10 +62363,10 @@ var init_registry2 = __esm({
|
|
|
62271
62363
|
if (this.#disposed || this.#sessions.get(session) !== runtime) return { status: "retired" };
|
|
62272
62364
|
return result2;
|
|
62273
62365
|
}
|
|
62274
|
-
async describeSessionAuthority(session) {
|
|
62366
|
+
async describeSessionAuthority(session, expectedSemanticPaneIds) {
|
|
62275
62367
|
const runtime = this.#runtime(session);
|
|
62276
62368
|
await runtime.whenReady();
|
|
62277
|
-
const authority2 = await this.#mirror.describeSessionAuthority(session);
|
|
62369
|
+
const authority2 = await this.#mirror.describeSessionAuthority(session, expectedSemanticPaneIds);
|
|
62278
62370
|
if (this.#disposed || this.#sessions.get(session) !== runtime) {
|
|
62279
62371
|
const error = new Error(`session runtime ${session} changed topology`);
|
|
62280
62372
|
error.name = "MirrorTopologyChangedError";
|
|
@@ -62805,7 +62897,7 @@ var init_registry2 = __esm({
|
|
|
62805
62897
|
return Promise.reject(error);
|
|
62806
62898
|
}
|
|
62807
62899
|
}
|
|
62808
|
-
sendInput(clientId, lease, semanticPaneId3, rawInput, performanceTraceId, rawCausalProbe, onCausalResult) {
|
|
62900
|
+
sendInput(clientId, lease, semanticPaneId3, rawInput, performanceTraceId, rawCausalProbe, onCausalResult, expectedLifetime) {
|
|
62809
62901
|
this.assertController(lease, clientId);
|
|
62810
62902
|
const inputLease = this.#authority.leaseFor(clientId, "input");
|
|
62811
62903
|
if (!inputLease) {
|
|
@@ -62832,7 +62924,8 @@ var init_registry2 = __esm({
|
|
|
62832
62924
|
incarnation: null
|
|
62833
62925
|
}) : null;
|
|
62834
62926
|
const started = this.#observability.enabled ? this.#observability.nowMicros() : 0;
|
|
62835
|
-
const replicaOwner = this.#terminalReplicaOwner(semanticPaneId3);
|
|
62927
|
+
const replicaOwner = expectedLifetime ? this.#terminalReplicas.get(semanticPaneId3) : this.#terminalReplicaOwner(semanticPaneId3);
|
|
62928
|
+
if (!replicaOwner) throw new Error("Input target lifetime unavailable");
|
|
62836
62929
|
if (causalProbe) {
|
|
62837
62930
|
this.#activeCausalCellProbes += 1;
|
|
62838
62931
|
let settled = false;
|
|
@@ -62855,6 +62948,8 @@ var init_registry2 = __esm({
|
|
|
62855
62948
|
this.#outputTraces.arm(semanticPaneId3, trace);
|
|
62856
62949
|
}
|
|
62857
62950
|
try {
|
|
62951
|
+
if (expectedLifetime && (expectedLifetime.generation !== this.generation || this.#terminalReplicas.get(semanticPaneId3) !== replicaOwner || replicaOwner.inputAdmissionIncarnation() !== expectedLifetime.incarnation))
|
|
62952
|
+
throw new Error("Input target lifetime changed");
|
|
62858
62953
|
if (input.kind === "text")
|
|
62859
62954
|
this.#mirror.sendText(
|
|
62860
62955
|
this.session,
|
|
@@ -63388,7 +63483,7 @@ var init_registry2 = __esm({
|
|
|
63388
63483
|
this.#assertOpen();
|
|
63389
63484
|
return this.#runtime.submitIntent(this.clientId, lease, operationId, intent);
|
|
63390
63485
|
}
|
|
63391
|
-
sendInput(lease, semanticPaneId3, input, performanceTraceId, causalProbe, onCausalResult) {
|
|
63486
|
+
sendInput(lease, semanticPaneId3, input, performanceTraceId, causalProbe, onCausalResult, expectedLifetime) {
|
|
63392
63487
|
this.#assertOpen();
|
|
63393
63488
|
this.#runtime.sendInput(
|
|
63394
63489
|
this.clientId,
|
|
@@ -63397,7 +63492,8 @@ var init_registry2 = __esm({
|
|
|
63397
63492
|
input,
|
|
63398
63493
|
performanceTraceId,
|
|
63399
63494
|
causalProbe,
|
|
63400
|
-
onCausalResult
|
|
63495
|
+
onCausalResult,
|
|
63496
|
+
expectedLifetime
|
|
63401
63497
|
);
|
|
63402
63498
|
}
|
|
63403
63499
|
failCausalCellProbe(semanticPaneId3, traceId, reason) {
|
|
@@ -63818,7 +63914,7 @@ var init_transport_binding = __esm({
|
|
|
63818
63914
|
authorize();
|
|
63819
63915
|
return authorize;
|
|
63820
63916
|
}
|
|
63821
|
-
sendInput(semanticPaneId3, input, performanceTraceId, causalProbe, onCausalResult) {
|
|
63917
|
+
sendInput(semanticPaneId3, input, performanceTraceId, causalProbe, onCausalResult, expectedLifetime) {
|
|
63822
63918
|
this.assertController(semanticPaneId3);
|
|
63823
63919
|
const lease = this.#shared.lease;
|
|
63824
63920
|
if (!lease) {
|
|
@@ -63838,7 +63934,8 @@ var init_transport_binding = __esm({
|
|
|
63838
63934
|
causalProbe ? (result2) => {
|
|
63839
63935
|
this.#causalCellProbes.delete(causalProbe.traceId);
|
|
63840
63936
|
onCausalResult?.(result2);
|
|
63841
|
-
} : onCausalResult
|
|
63937
|
+
} : onCausalResult,
|
|
63938
|
+
expectedLifetime
|
|
63842
63939
|
);
|
|
63843
63940
|
} catch (error) {
|
|
63844
63941
|
if (causalProbe) this.#causalCellProbes.delete(causalProbe.traceId);
|
|
@@ -70131,6 +70228,7 @@ var init_pane_stream_websocket = __esm({
|
|
|
70131
70228
|
"use strict";
|
|
70132
70229
|
init_src2();
|
|
70133
70230
|
init_src2();
|
|
70231
|
+
init_src2();
|
|
70134
70232
|
init_admission_util();
|
|
70135
70233
|
init_registry2();
|
|
70136
70234
|
init_terminal_delivery_observation_identity();
|
|
@@ -70259,7 +70357,10 @@ var init_pane_stream_websocket = __esm({
|
|
|
70259
70357
|
try {
|
|
70260
70358
|
const describeStartedAtMicros = trace ? this.#observability.nowMicros() : 0;
|
|
70261
70359
|
if (this.#mirror.describeSessionAuthority) {
|
|
70262
|
-
const authority2 = await this.#mirror.describeSessionAuthority(
|
|
70360
|
+
const authority2 = await this.#mirror.describeSessionAuthority(
|
|
70361
|
+
context.sessionName,
|
|
70362
|
+
request3.panes
|
|
70363
|
+
);
|
|
70263
70364
|
described = authority2.description;
|
|
70264
70365
|
runtimeSessionId = authority2.runtimeSessionId;
|
|
70265
70366
|
} else {
|
|
@@ -70839,6 +70940,9 @@ var init_pane_stream_websocket = __esm({
|
|
|
70839
70940
|
try {
|
|
70840
70941
|
sendControl2(this.#socket, {
|
|
70841
70942
|
type: "ready",
|
|
70943
|
+
...this.#sessionRuntimeBinding && this.#descriptor.terminalDelivery?.protocolVersions.includes(
|
|
70944
|
+
PANE_STREAM_INPUT_LIFETIME_CAPABILITY_VERSION
|
|
70945
|
+
) ? { inputLifetime: true } : {},
|
|
70842
70946
|
protocolVersion: PANE_STREAM_PROTOCOL_VERSION,
|
|
70843
70947
|
daemonInstanceId: this.#binding.daemonInstanceId,
|
|
70844
70948
|
requestId: this.#binding.requestId,
|
|
@@ -71896,7 +72000,8 @@ var init_pane_stream_websocket = __esm({
|
|
|
71896
72000
|
frame.causalProbe,
|
|
71897
72001
|
ingressAtMicros,
|
|
71898
72002
|
callbackAtSharedMicros,
|
|
71899
|
-
ingressAtSharedMicros
|
|
72003
|
+
ingressAtSharedMicros,
|
|
72004
|
+
frame.expectedLifetime
|
|
71900
72005
|
);
|
|
71901
72006
|
};
|
|
71902
72007
|
#acceptAuthorityGeneration(generation) {
|
|
@@ -71989,7 +72094,13 @@ var init_pane_stream_websocket = __esm({
|
|
|
71989
72094
|
this.#ledger.give(this.#clientId, pane, "renderer-backlog", returned);
|
|
71990
72095
|
this.#evaluateResume(pane);
|
|
71991
72096
|
}
|
|
71992
|
-
#acceptInput(pane, seq, kind, data, frameBytes, performanceTraceId, causalProbe, ingressAtMicros = null, callbackAtSharedMicros = null, ingressAtSharedMicros = null) {
|
|
72097
|
+
#acceptInput(pane, seq, kind, data, frameBytes, performanceTraceId, causalProbe, ingressAtMicros = null, callbackAtSharedMicros = null, ingressAtSharedMicros = null, expectedLifetime) {
|
|
72098
|
+
if (expectedLifetime && (!this.#sessionRuntimeBinding || !this.#descriptor.terminalDelivery?.protocolVersions.includes(
|
|
72099
|
+
PANE_STREAM_INPUT_LIFETIME_CAPABILITY_VERSION
|
|
72100
|
+
))) {
|
|
72101
|
+
this.#failProtocol("input-rejected");
|
|
72102
|
+
return;
|
|
72103
|
+
}
|
|
71993
72104
|
if (this.#descriptor.viewerMode !== "interactive") {
|
|
71994
72105
|
this.#failProtocol("input-rejected");
|
|
71995
72106
|
return;
|
|
@@ -72081,7 +72192,8 @@ var init_pane_stream_websocket = __esm({
|
|
|
72081
72192
|
}
|
|
72082
72193
|
});
|
|
72083
72194
|
}
|
|
72084
|
-
} : void 0
|
|
72195
|
+
} : void 0,
|
|
72196
|
+
expectedLifetime
|
|
72085
72197
|
);
|
|
72086
72198
|
else if (kind === "text") channel.sub.sendText(data);
|
|
72087
72199
|
else channel.sub.sendKey(data);
|
package/package.json
CHANGED
|
@@ -230,6 +230,16 @@ export type PaneStreamRedeemFrame = z.infer<typeof PaneStreamRedeemFrameSchemaZ>
|
|
|
230
230
|
/** @deprecated Import SessionRuntimeTerminalKeyNameSchemaZ for new code. */
|
|
231
231
|
export const PaneStreamKeyNameSchemaZ = SessionRuntimeTerminalKeyNameSchemaZ;
|
|
232
232
|
|
|
233
|
+
/** Negotiated only with callers offering this additive delivery capability. */
|
|
234
|
+
export const PANE_STREAM_INPUT_LIFETIME_CAPABILITY_VERSION = 105;
|
|
235
|
+
export const PaneStreamInputLifetimeSchemaZ = z
|
|
236
|
+
.object({
|
|
237
|
+
generation: z.string().min(1).max(256),
|
|
238
|
+
incarnation: z.string().min(1).max(256),
|
|
239
|
+
})
|
|
240
|
+
.strict();
|
|
241
|
+
export type PaneStreamInputLifetime = z.infer<typeof PaneStreamInputLifetimeSchemaZ>;
|
|
242
|
+
|
|
233
243
|
const PaneStreamInputFrameMetadataShape = {
|
|
234
244
|
type: z.literal("input"),
|
|
235
245
|
pane: PaneStreamSemanticPaneIdSchemaZ,
|
|
@@ -237,6 +247,7 @@ const PaneStreamInputFrameMetadataShape = {
|
|
|
237
247
|
/** Opt-in controlled next-output probe; not a general causal assertion. */
|
|
238
248
|
performanceTraceId: z.uuid().optional(),
|
|
239
249
|
causalProbe: CausalCellProbeV1SchemaZ.optional(),
|
|
250
|
+
expectedLifetime: PaneStreamInputLifetimeSchemaZ.optional(),
|
|
240
251
|
} as const;
|
|
241
252
|
|
|
242
253
|
export const PaneStreamInputFrameSchemaZ = z
|
|
@@ -409,6 +420,7 @@ const CellCoordinateSchemaZ = z.number().int().min(0).max(PANE_STREAM_MAX_GRID_C
|
|
|
409
420
|
export const PaneStreamReadyFrameSchemaZ = z
|
|
410
421
|
.object({
|
|
411
422
|
type: z.literal("ready"),
|
|
423
|
+
inputLifetime: z.literal(true).optional(),
|
|
412
424
|
protocolVersion: z.literal(PANE_STREAM_PROTOCOL_VERSION),
|
|
413
425
|
daemonInstanceId: BoundedIdentitySchemaZ,
|
|
414
426
|
requestId: z.uuid(),
|
|
@@ -7,6 +7,8 @@ import { createBufferedFnv64, type BufferedFnv64 } from "./terminal-fnv64-wasm.t
|
|
|
7
7
|
|
|
8
8
|
const ROW_HASH_CACHE = new WeakMap<object, string>();
|
|
9
9
|
const DEEPLY_FROZEN_ROWS = new WeakSet<object>();
|
|
10
|
+
// Provenance from scalar construction only, never generic frozen-object checks.
|
|
11
|
+
const DECODED_ROWS = new WeakSet<object>();
|
|
10
12
|
const UTF8_ENCODER = new TextEncoder();
|
|
11
13
|
// Fixed ASCII headers cover common terminal strings without retaining values.
|
|
12
14
|
const SHORT_ASCII_HEADERS = Array.from({ length: 33 }, (_, length) => `s${length}:`);
|
|
@@ -600,8 +602,9 @@ class DecodedTerminalReplicaRowBuilder {
|
|
|
600
602
|
cells: Object.freeze(cells),
|
|
601
603
|
wrapped,
|
|
602
604
|
}) as unknown as TerminalReplicaRow;
|
|
603
|
-
//
|
|
605
|
+
// Existing row hashing remains lazy and unchanged.
|
|
604
606
|
DEEPLY_FROZEN_ROWS.add(row);
|
|
607
|
+
DECODED_ROWS.add(row);
|
|
605
608
|
return row;
|
|
606
609
|
}
|
|
607
610
|
|
|
@@ -610,6 +613,10 @@ class DecodedTerminalReplicaRowBuilder {
|
|
|
610
613
|
}
|
|
611
614
|
}
|
|
612
615
|
|
|
616
|
+
export function isDecodedTerminalReplicaRow(row: unknown): row is TerminalReplicaRow {
|
|
617
|
+
return typeof row === "object" && row !== null && DECODED_ROWS.has(row);
|
|
618
|
+
}
|
|
619
|
+
|
|
613
620
|
export function createDecodedTerminalReplicaRowBuilder() {
|
|
614
621
|
return new DecodedTerminalReplicaRowBuilder();
|
|
615
622
|
}
|
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
<key>CFBundlePackageType</key>
|
|
22
22
|
<string>APPL</string>
|
|
23
23
|
<key>CFBundleShortVersionString</key>
|
|
24
|
-
<string>2.9.
|
|
24
|
+
<string>2.9.11</string>
|
|
25
25
|
<key>CFBundleVersion</key>
|
|
26
|
-
<string>2.9.
|
|
26
|
+
<string>2.9.11</string>
|
|
27
27
|
<key>LSMinimumSystemVersion</key>
|
|
28
28
|
<string>11.0</string>
|
|
29
29
|
<key>LSUIElement</key>
|
|
Binary file
|
|
Binary file
|
package/packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/_CodeSignature/CodeResources
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
</data>
|
|
11
11
|
<key>Resources/Assets.car</key>
|
|
12
12
|
<data>
|
|
13
|
-
|
|
13
|
+
nBfyKmj9/xOSU1E6fMrLP0j34to=
|
|
14
14
|
</data>
|
|
15
15
|
</dict>
|
|
16
16
|
<key>files2</key>
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
<dict>
|
|
27
27
|
<key>hash2</key>
|
|
28
28
|
<data>
|
|
29
|
-
|
|
29
|
+
BH5ZBbufHUMGSzMRXcEqBgur+e94BeWVItaM9FDWrFA=
|
|
30
30
|
</data>
|
|
31
31
|
</dict>
|
|
32
32
|
</dict>
|
|
@@ -84,11 +84,21 @@ export class MirrorService {
|
|
|
84
84
|
this.release(session, entry);
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
|
-
async describeSessionAuthority(session) {
|
|
87
|
+
async describeSessionAuthority(session, expectedSemanticPaneIds) {
|
|
88
88
|
const entry = await this.acquire(session);
|
|
89
89
|
try {
|
|
90
90
|
const identity = await entry.channel.attachedSessionIdentity();
|
|
91
|
-
|
|
91
|
+
let description = entry.channel.describe();
|
|
92
|
+
if (expectedSemanticPaneIds?.some((id) => !description.panes.some((pane) => pane.semanticPaneId === id))) {
|
|
93
|
+
// A mutation receipt and fresh catalog can precede debounced mirror
|
|
94
|
+
// discovery. Join the verified native inventory before declaring a
|
|
95
|
+
// requested pane absent; never substitute receipt IDs for tmux truth.
|
|
96
|
+
await entry.channel.describeTrustedInventory(identity.runtimeSessionId, true);
|
|
97
|
+
description = entry.channel.describe();
|
|
98
|
+
}
|
|
99
|
+
if (this.disposed || entry.retired || this.channels.get(session) !== entry)
|
|
100
|
+
throw new Error("Mirror authority retired during description");
|
|
101
|
+
return { description, runtimeSessionId: identity.runtimeSessionId };
|
|
92
102
|
}
|
|
93
103
|
finally {
|
|
94
104
|
this.release(session, entry);
|