tmux-ide 2.9.2 → 2.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/bin/cli.js +2071 -625
- package/package.json +14 -5
- package/packages/contracts/src/desktop-host.ts +3 -0
- package/packages/contracts/src/saved-machines.ts +19 -0
- package/packages/contracts/src/terminal-replica.ts +1 -1
- package/packages/core/package.json +3 -2
- package/packages/core/src/terminal-delivery.ts +51 -3
- package/packages/core/src/terminal-fnv64-wasm.ts +4 -3
- package/packages/core/src/terminal-replica-hash-cache.ts +129 -31
- package/packages/core/src/terminal-replica-owned-row.ts +27 -0
- package/packages/core/src/terminal-replica.ts +13 -28
- package/packages/daemon/dist/command-center/daemon-fleet-facts-observer.js +96 -10
- package/packages/daemon/dist/command-center/resources/saved-machine-route.js +40 -1
- package/packages/daemon/dist/command-center/ws-events.js +5 -24
- package/packages/daemon/dist/lib/canonical-daemon-bootstrap.js +8 -0
- package/packages/daemon/dist/lib/canonical-daemon.js +28 -2
- package/packages/daemon/dist/lib/daemon-embed.js +1 -1
- package/packages/daemon/dist/lib/daemon-service-manager.js +122 -0
- package/packages/daemon/dist/lib/daemon-service-plan.js +127 -0
- package/packages/daemon/dist/lib/daemon-service.js +259 -0
- package/packages/daemon/dist/lib/install-origin.js +2 -0
- package/packages/daemon/dist/lib/local-fleet-request.js +9 -3
- package/packages/daemon/dist/lib/log.js +6 -10
- package/packages/daemon/dist/lib/managed-installer-update.js +67 -0
- package/packages/daemon/dist/lib/{tui-download-lock.js → private-operation-lock.js} +11 -11
- package/packages/daemon/dist/lib/remote-daemon-info.js +3 -2
- package/packages/daemon/dist/lib/remote-daemon-lifecycle.js +4 -4
- package/packages/daemon/dist/lib/remote-tmux-command.js +10 -0
- package/packages/daemon/dist/lib/runtime-namespace.js +28 -16
- package/packages/daemon/dist/lib/saved-machines.js +40 -2
- package/packages/daemon/dist/lib/ssh-daemon-transport.js +24 -9
- package/packages/daemon/dist/lib/tmux-server-owner.js +1 -1
- package/packages/daemon/dist/lib/tmux-server-registration.js +21 -3
- package/packages/daemon/dist/lib/tui-binary.js +2 -2
- package/packages/daemon/dist/lib/update.js +18 -0
- package/packages/daemon/dist/lib/workspace-multiplexer-verbs.js +24 -1
- package/packages/daemon/dist/machines.js +40 -4
- 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/attachments/direct-websocket.js +4 -1
- package/packages/daemon/dist/terminal/attachments/native-runtime.js +22 -13
- package/packages/daemon/dist/terminal/mirror/mirror-service.js +101 -3
- package/packages/daemon/dist/terminal/mirror/registered-window-guard.js +62 -0
- package/packages/daemon/dist/terminal/mirror/session-channel.js +75 -4
- package/packages/daemon/dist/terminal/mirror/shared-window-index.js +45 -0
- package/packages/daemon/dist/terminal/pane-stream/pane-stream-websocket.js +11 -1
- package/packages/daemon/dist/terminal/session-runtime/multiplexer-backend.js +1 -0
- package/packages/daemon/dist/terminal/session-runtime/registry.js +56 -7
- package/packages/daemon/dist/terminal/session-runtime/semantic-mutation-executor.js +3 -1
- package/packages/daemon/dist/tui/mirror/dialog-model.js +2 -35
- package/packages/daemon/dist/tui/mirror/runtime/application-daemon-authority-owner.js +8 -0
- package/packages/daemon/dist/tui/mirror/runtime/application-home-fleet.js +20 -2
- package/packages/daemon/dist/tui/mirror/runtime/application-machine-agents.js +7 -1
- package/packages/daemon/dist/tui/mirror/runtime/application-machine-authority.js +59 -9
- package/packages/daemon/dist/tui/mirror/runtime/application-machine-navigation.js +27 -19
- package/packages/daemon/dist/tui/mirror/runtime/application-machine-sidebar.jsx +23 -18
- package/packages/daemon/dist/tui/mirror/runtime/application-machine-startup.js +31 -2
- package/packages/daemon/dist/tui/mirror/runtime/application-palette-search-owner.js +7 -3
- package/packages/daemon/dist/tui/mirror/runtime/application-performance-log.js +3 -0
- package/packages/daemon/dist/tui/mirror/runtime/application-terminal-input-ingress.js +146 -2
- package/packages/daemon/dist/tui/mirror/runtime/application-terminal-interaction-controller.js +201 -50
- package/packages/daemon/dist/tui/mirror/runtime/bounded-performance-record-writer.js +50 -10
- package/packages/daemon/dist/tui/mirror/runtime/terminal-fast-lane-renderer-adapter.js +6 -5
- package/packages/daemon/dist/tui/mirror/runtime/terminal-pane-input-router.js +3 -0
- package/packages/daemon/dist/tui/mirror/runtime/workspace-terminal-fast-lane.js +8 -2
- package/packages/daemon/dist/tui/mirror/terminal-text.js +35 -0
- package/packages/daemon/dist/tui/mirror/workspace/connection-feedback.js +5 -3
- package/packages/daemon/src/command-center/daemon-fleet-facts-observer.ts +100 -10
- package/packages/daemon/src/command-center/resources/saved-machine-route.ts +48 -1
- package/packages/daemon/src/command-center/ws-events.ts +5 -25
- package/packages/daemon/src/lib/canonical-daemon-bootstrap.ts +12 -0
- package/packages/daemon/src/lib/canonical-daemon.ts +44 -2
- package/packages/daemon/src/lib/daemon-embed.ts +1 -0
- package/packages/daemon/src/lib/daemon-service-manager.ts +152 -0
- package/packages/daemon/src/lib/daemon-service-plan.ts +153 -0
- package/packages/daemon/src/lib/daemon-service.ts +301 -0
- package/packages/daemon/src/lib/install-origin.ts +5 -0
- package/packages/daemon/src/lib/local-fleet-request.ts +19 -3
- package/packages/daemon/src/lib/log.ts +13 -9
- package/packages/daemon/src/lib/managed-installer-update.ts +79 -0
- package/packages/daemon/src/lib/{tui-download-lock.ts → private-operation-lock.ts} +15 -11
- package/packages/daemon/src/lib/remote-daemon-info.ts +3 -3
- package/packages/daemon/src/lib/remote-daemon-lifecycle.ts +4 -4
- package/packages/daemon/src/lib/remote-tmux-command.ts +12 -0
- package/packages/daemon/src/lib/runtime-namespace.ts +27 -18
- package/packages/daemon/src/lib/saved-machines.ts +40 -1
- package/packages/daemon/src/lib/ssh-daemon-transport.ts +25 -7
- package/packages/daemon/src/lib/tmux-server-owner.ts +1 -0
- package/packages/daemon/src/lib/tmux-server-registration.ts +21 -3
- package/packages/daemon/src/lib/tui-binary.ts +2 -2
- package/packages/daemon/src/lib/update.ts +24 -0
- package/packages/daemon/src/lib/workspace-multiplexer-verbs.ts +22 -0
- package/packages/daemon/src/machines.ts +53 -5
- package/packages/daemon/src/terminal/attachments/direct-websocket.ts +8 -2
- package/packages/daemon/src/terminal/attachments/native-runtime.ts +28 -13
- package/packages/daemon/src/terminal/mirror/mirror-service.ts +105 -3
- package/packages/daemon/src/terminal/mirror/registered-window-guard.ts +66 -0
- package/packages/daemon/src/terminal/mirror/session-channel.ts +92 -4
- package/packages/daemon/src/terminal/mirror/shared-window-index.ts +42 -0
- package/packages/daemon/src/terminal/pane-stream/pane-stream-websocket.ts +12 -1
- package/packages/daemon/src/terminal/session-runtime/multiplexer-backend.ts +2 -0
- package/packages/daemon/src/terminal/session-runtime/registry.ts +70 -8
- package/packages/daemon/src/terminal/session-runtime/semantic-mutation-executor.ts +3 -1
- package/packages/daemon/src/tui/mirror/dialog-model.ts +2 -32
- package/packages/daemon/src/tui/mirror/runtime/application-daemon-authority-owner.ts +8 -0
- package/packages/daemon/src/tui/mirror/runtime/application-home-fleet.ts +19 -2
- package/packages/daemon/src/tui/mirror/runtime/application-machine-agents.ts +6 -1
- package/packages/daemon/src/tui/mirror/runtime/application-machine-authority.ts +60 -11
- package/packages/daemon/src/tui/mirror/runtime/application-machine-navigation.ts +39 -33
- package/packages/daemon/src/tui/mirror/runtime/application-machine-sidebar.tsx +31 -23
- package/packages/daemon/src/tui/mirror/runtime/application-machine-startup.ts +38 -2
- package/packages/daemon/src/tui/mirror/runtime/application-palette-search-owner.ts +7 -4
- package/packages/daemon/src/tui/mirror/runtime/application-performance-log.ts +3 -0
- package/packages/daemon/src/tui/mirror/runtime/application-root-v2.tsx +1 -1
- package/packages/daemon/src/tui/mirror/runtime/application-shell-view.tsx +47 -46
- package/packages/daemon/src/tui/mirror/runtime/application-terminal-input-ingress.ts +165 -2
- package/packages/daemon/src/tui/mirror/runtime/application-terminal-interaction-controller.ts +207 -53
- package/packages/daemon/src/tui/mirror/runtime/bounded-performance-record-writer.ts +49 -9
- package/packages/daemon/src/tui/mirror/runtime/terminal-fast-lane-renderer-adapter.ts +6 -5
- package/packages/daemon/src/tui/mirror/runtime/terminal-pane-input-router.ts +4 -0
- package/packages/daemon/src/tui/mirror/runtime/workspace-terminal-fast-lane.ts +8 -3
- package/packages/daemon/src/tui/mirror/terminal-text.ts +32 -0
- package/packages/daemon/src/tui/mirror/workspace/connection-feedback.ts +6 -3
- package/packages/daemon-client/src/fleet-connection-status.ts +10 -1
- package/packages/daemon-client/src/workspace-client.ts +4 -1
- package/packages/contracts/src/__tests__/actions-contract.test.ts +0 -119
- package/packages/contracts/src/__tests__/agent-graph-overlay.test.ts +0 -428
- package/packages/contracts/src/__tests__/app-window-mutation.test.ts +0 -51
- package/packages/contracts/src/__tests__/app-window-state.test.ts +0 -34
- package/packages/contracts/src/__tests__/application-shell.test.ts +0 -645
- package/packages/contracts/src/__tests__/automation-operations.test.ts +0 -78
- package/packages/contracts/src/__tests__/causal-cell.test.ts +0 -47
- package/packages/contracts/src/__tests__/client-view-state.test.ts +0 -115
- package/packages/contracts/src/__tests__/cohesion-fixture.test.ts +0 -106
- package/packages/contracts/src/__tests__/commands.test.ts +0 -86
- package/packages/contracts/src/__tests__/control.test.ts +0 -154
- package/packages/contracts/src/__tests__/daemon-events.test.ts +0 -405
- package/packages/contracts/src/__tests__/daemon-resources.test.ts +0 -143
- package/packages/contracts/src/__tests__/daemon-wire.test.ts +0 -149
- package/packages/contracts/src/__tests__/desktop-host.test.ts +0 -269
- package/packages/contracts/src/__tests__/desktop-missions.test.ts +0 -215
- package/packages/contracts/src/__tests__/experience-conformance.test.ts +0 -153
- package/packages/contracts/src/__tests__/experience-kernel-boundary.test.ts +0 -113
- package/packages/contracts/src/__tests__/experience-shell.test.ts +0 -65
- package/packages/contracts/src/__tests__/fixtures/daemon-wire-v2.json +0 -35
- package/packages/contracts/src/__tests__/fixtures/daemon-wire-v3.json +0 -35
- package/packages/contracts/src/__tests__/fixtures/daemon-wire-v4.json +0 -35
- package/packages/contracts/src/__tests__/fixtures/scoped-receipt.ts +0 -62
- package/packages/contracts/src/__tests__/fleet-agent-graph.test.ts +0 -231
- package/packages/contracts/src/__tests__/fleet-catalog.test.ts +0 -270
- package/packages/contracts/src/__tests__/fleet-lifecycle.test.ts +0 -62
- package/packages/contracts/src/__tests__/focus-overlay.test.ts +0 -110
- package/packages/contracts/src/__tests__/ide-config.test.ts +0 -64
- package/packages/contracts/src/__tests__/interaction-evidence.test.ts +0 -288
- package/packages/contracts/src/__tests__/interaction-receipt-v2.test.ts +0 -72
- package/packages/contracts/src/__tests__/issue-error.test.ts +0 -78
- package/packages/contracts/src/__tests__/mission-projections.test.ts +0 -186
- package/packages/contracts/src/__tests__/missions.test.ts +0 -272
- package/packages/contracts/src/__tests__/multiplexer-verbs.test.ts +0 -242
- package/packages/contracts/src/__tests__/pane-appearance.test.ts +0 -146
- package/packages/contracts/src/__tests__/pane-read-result.test.ts +0 -55
- package/packages/contracts/src/__tests__/pane-stream.test.ts +0 -536
- package/packages/contracts/src/__tests__/pane-widget-marker.test.ts +0 -327
- package/packages/contracts/src/__tests__/performance-metrics.test.ts +0 -73
- package/packages/contracts/src/__tests__/performance-qualification.test.ts +0 -137
- package/packages/contracts/src/__tests__/rich-card-widget.test.ts +0 -29
- package/packages/contracts/src/__tests__/session-runtime.test.ts +0 -512
- package/packages/contracts/src/__tests__/startup-readiness.test.ts +0 -409
- package/packages/contracts/src/__tests__/terminal-attachment-stream.test.ts +0 -72
- package/packages/contracts/src/__tests__/terminal-attachments.test.ts +0 -329
- package/packages/contracts/src/__tests__/terminal-delivery.test.ts +0 -88
- package/packages/contracts/src/__tests__/terminal-runtime-inventory.test.ts +0 -68
- package/packages/contracts/src/__tests__/terminals.test.ts +0 -87
- package/packages/contracts/src/__tests__/tmux-server-scope.test.ts +0 -166
- package/packages/contracts/src/__tests__/transport-contract-loading.test.ts +0 -91
- package/packages/contracts/src/__tests__/visual-tokens.test.ts +0 -224
- package/packages/contracts/src/__tests__/window-links.test.ts +0 -243
- package/packages/contracts/src/__tests__/workspace-changes-resource.test.ts +0 -317
- package/packages/contracts/src/__tests__/workspace-changes-view.test.ts +0 -122
- package/packages/contracts/src/__tests__/workspace-config.test.ts +0 -294
- package/packages/contracts/src/__tests__/workspace-files-resource.test.ts +0 -261
- package/packages/contracts/src/__tests__/workspace-files-tree.test.ts +0 -147
- package/packages/contracts/src/__tests__/workspace-pane-creation.test.ts +0 -249
- package/packages/contracts/src/__tests__/workspace-promotion.test.ts +0 -94
- package/packages/contracts/src/__tests__/workspace-resource-identity.test.ts +0 -90
- package/packages/contracts/src/daemon-resource-request.test.ts +0 -192
- package/packages/contracts/src/native-operation-identity.test.ts +0 -23
- package/packages/contracts/src/workspace-admission.test.ts +0 -21
- package/packages/contracts/src/workspace-catalog-resource.test.ts +0 -146
- package/packages/core/src/agent-provisioning.test.ts +0 -42
- package/packages/core/src/application-shell-session.test.ts +0 -105
- package/packages/core/src/interaction-evidence.test.ts +0 -134
- package/packages/core/src/interaction-flow.test.ts +0 -66
- package/packages/core/src/interaction-receipts.test.ts +0 -671
- package/packages/core/src/navigator.test.ts +0 -34
- package/packages/core/src/optimistic-projection-conformance.test.ts +0 -75
- package/packages/core/src/optimistic-projection.test.ts +0 -118
- package/packages/core/src/performance-metrics.test.ts +0 -121
- package/packages/core/src/performance-qualification.test.ts +0 -283
- package/packages/core/src/saved-machines.test.ts +0 -80
- package/packages/core/src/terminal-compact-cold.test.ts +0 -87
- package/packages/core/src/terminal-conformance.test.ts +0 -48
- package/packages/core/src/terminal-delivery-cache-lifetime.test.ts +0 -167
- package/packages/core/src/terminal-delivery-encode-cooperative.test.ts +0 -140
- package/packages/core/src/terminal-delivery-representation-hash.test.ts +0 -77
- package/packages/core/src/terminal-delivery.test.ts +0 -1471
- package/packages/core/src/terminal-fnv64-wasm.test.ts +0 -61
- package/packages/core/src/terminal-replica-cold.test.ts +0 -31
- package/packages/core/src/terminal-replica-cooperative.test.ts +0 -170
- package/packages/core/src/terminal-replica-hash-cache.test.ts +0 -283
- package/packages/core/src/terminal-replica.test.ts +0 -347
- package/packages/core/src/workspace-selection.test.ts +0 -63
- package/packages/daemon/dist/__tests__/support.js +0 -33
- package/packages/daemon/dist/lib/__tests__/fixtures/workspace-state-writer.js +0 -58
- package/packages/daemon/dist/lib/__tests__/installed-recovery-fixture.js +0 -400
- package/packages/daemon/dist/terminal/__tests__/MockPtyAdapter.js +0 -182
- package/packages/daemon/dist/terminal/mirror/__tests__/scripted-channel.js +0 -98
- package/packages/daemon/dist/terminal/mirror/__tests__/simulated-channel.js +0 -156
- package/packages/daemon/src/tui/mirror/__snapshots__/activity-surface-renderer.test.tsx.snap +0 -42
- package/packages/daemon/src/tui/mirror/__snapshots__/changes-terminal-surface-renderer.test.tsx.snap +0 -267
- package/packages/daemon/src/tui/mirror/__snapshots__/home-files-surface-renderer.test.tsx.snap +0 -267
- package/packages/daemon/src/tui/mirror/__snapshots__/missions-surface-renderer.test.tsx.snap +0 -134
- package/packages/daemon/src/tui/mirror/__snapshots__/recipes-gallery-renderer.test.tsx.snap +0 -141
- package/packages/daemon/src/tui/mirror/__snapshots__/shell-chrome-renderer.test.tsx.snap +0 -134
- package/packages/daemon/src/tui/mirror/runtime/__snapshots__/application-shell-view-renderer.test.tsx.snap +0 -87
- package/packages/daemon/src/tui/mirror/workspace/__snapshots__/agent-terminal-canvas-renderer.test.tsx.snap +0 -348
- package/packages/daemon/src/tui/mirror/workspace/__snapshots__/application-shell-renderer.test.tsx.snap +0 -134
- package/packages/daemon/src/tui/mirror/workspace/__snapshots__/command-palette-surface-renderer.test.tsx.snap +0 -255
- package/packages/daemon/src/tui/mirror/workspace/__snapshots__/pane-frame-renderer.test.tsx.snap +0 -525
- package/packages/daemon/src/tui/mirror/workspace/__snapshots__/terminal-pane-header-polish-renderer.test.tsx.snap +0 -31
- package/packages/daemon/src/tui/mirror/workspace/__snapshots__/workbench-shell-renderer.test.tsx.snap +0 -134
- package/packages/daemon-client/src/application-shell-session.test.ts +0 -196
- package/packages/daemon-client/src/automation-client.test.ts +0 -214
- package/packages/daemon-client/src/bootstrap-coordinator.test.ts +0 -145
- package/packages/daemon-client/src/connection-supervisor.test.ts +0 -109
- package/packages/daemon-client/src/direct-application-shell-transport.test.ts +0 -941
- package/packages/daemon-client/src/first-latest-coordinator.test.ts +0 -175
- package/packages/daemon-client/src/fleet-dial-scheduler.test.ts +0 -114
- package/packages/daemon-client/src/fleet-environments.test.ts +0 -40
- package/packages/daemon-client/src/generation-bound-store-timers.test.ts +0 -74
- package/packages/daemon-client/src/owner-action-client.test.ts +0 -245
- package/packages/daemon-client/src/pane-stream-client.test.ts +0 -2841
- package/packages/daemon-client/src/pane-stream-clock-calibration.test.ts +0 -207
- package/packages/daemon-client/src/pane-stream-loopback-benchmark.test.ts +0 -51
- package/packages/daemon-client/src/push-resource-session.test.ts +0 -509
- package/packages/daemon-client/src/resource-replica.test.ts +0 -186
- package/packages/daemon-client/src/runtime-resource-ledger.test.ts +0 -18
- package/packages/daemon-client/src/scoped-tmux-server-transport.test.ts +0 -114
- package/packages/daemon-client/src/terminal-fast-lane.test.ts +0 -835
- package/packages/daemon-client/src/tmux-server-client.test.ts +0 -279
- package/packages/daemon-client/src/tmux-server-interaction-events.test.ts +0 -230
- package/packages/daemon-client/src/workspace-catalog-v2.test.ts +0 -109
- package/packages/daemon-client/src/workspace-client-boundaries.test.ts +0 -59
- package/packages/daemon-client/src/workspace-client-operations.test.ts +0 -96
- package/packages/daemon-client/src/workspace-client.test.ts +0 -2912
- package/packages/daemon-client/src/workspace-event-supervisor.test.ts +0 -1086
- package/packages/daemon-client/src/workspace-pane-client.test.ts +0 -80
- package/packages/presentation/src/presentation-contract.test.ts +0 -63
- package/packages/tmux-bridge/src/runner.test.ts +0 -614
- package/packages/tmux-bridge/src/targeting.test.ts +0 -107
|
@@ -6,21 +6,26 @@ export interface PerformanceRecordSink {
|
|
|
6
6
|
export class BoundedPerformanceRecordWriter {
|
|
7
7
|
readonly #sink: PerformanceRecordSink;
|
|
8
8
|
readonly #criticalLimit: number;
|
|
9
|
-
readonly #pendingCritical = new
|
|
9
|
+
readonly #pendingCritical = new Set<string>();
|
|
10
|
+
readonly #pending: { record: string; bytes: number; key?: string }[] = [];
|
|
11
|
+
readonly #pendingByteLimit: number;
|
|
12
|
+
#pendingBytes = 0;
|
|
13
|
+
#flushPromise: Promise<void> | null = null;
|
|
14
|
+
#resolveFlush: (() => void) | null = null;
|
|
10
15
|
#saturated = false;
|
|
11
16
|
#failed = false;
|
|
12
17
|
#droppedRecords = 0;
|
|
13
18
|
|
|
14
|
-
constructor(sink: PerformanceRecordSink, criticalLimit = 16) {
|
|
19
|
+
constructor(sink: PerformanceRecordSink, criticalLimit = 16, pendingByteLimit = 64 * 1024) {
|
|
15
20
|
this.#sink = sink;
|
|
16
21
|
this.#criticalLimit = criticalLimit;
|
|
22
|
+
this.#pendingByteLimit = pendingByteLimit;
|
|
17
23
|
}
|
|
18
24
|
|
|
19
25
|
write(record: string): boolean {
|
|
20
26
|
if (this.#failed) return false;
|
|
21
27
|
if (this.#saturated) {
|
|
22
|
-
this.#
|
|
23
|
-
return false;
|
|
28
|
+
return this.#enqueue(record);
|
|
24
29
|
}
|
|
25
30
|
return this.#writeAccepted(record);
|
|
26
31
|
}
|
|
@@ -33,22 +38,57 @@ export class BoundedPerformanceRecordWriter {
|
|
|
33
38
|
this.#droppedRecords += 1;
|
|
34
39
|
return false;
|
|
35
40
|
}
|
|
36
|
-
this.#
|
|
37
|
-
return true;
|
|
41
|
+
return this.#enqueue(record, key);
|
|
38
42
|
}
|
|
39
43
|
|
|
40
44
|
drain(): void {
|
|
41
45
|
if (this.#failed) return;
|
|
42
46
|
this.#saturated = false;
|
|
43
|
-
|
|
44
|
-
this.#
|
|
45
|
-
|
|
47
|
+
while (this.#pending.length > 0 && !this.#saturated && !this.#failed) {
|
|
48
|
+
const next = this.#pending.shift()!;
|
|
49
|
+
this.#pendingBytes -= next.bytes;
|
|
50
|
+
if (next.key !== undefined) this.#pendingCritical.delete(next.key);
|
|
51
|
+
this.#writeAccepted(next.record);
|
|
46
52
|
}
|
|
53
|
+
if (this.#pending.length === 0) this.#finishFlush();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Wait until retained records reach the stream; its owner then flushes/end()s it. */
|
|
57
|
+
flush(): Promise<void> {
|
|
58
|
+
if (this.#failed || this.#pending.length === 0) return Promise.resolve();
|
|
59
|
+
this.#flushPromise ??= new Promise((resolve) => {
|
|
60
|
+
this.#resolveFlush = resolve;
|
|
61
|
+
});
|
|
62
|
+
return this.#flushPromise;
|
|
47
63
|
}
|
|
48
64
|
|
|
49
65
|
fail(): void {
|
|
50
66
|
this.#failed = true;
|
|
51
67
|
this.#pendingCritical.clear();
|
|
68
|
+
this.#pending.length = 0;
|
|
69
|
+
this.#pendingBytes = 0;
|
|
70
|
+
this.#finishFlush();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
#enqueue(record: string, key?: string): boolean {
|
|
74
|
+
const bytes = Buffer.byteLength(record);
|
|
75
|
+
// Ordinary bursts get one extra stream-sized buffer. Critical records have
|
|
76
|
+
// a separate byte reserve as well as their existing key-count limit.
|
|
77
|
+
const limit = this.#pendingByteLimit + (key === undefined ? 0 : 64 * 1024);
|
|
78
|
+
if (this.#pending.length >= 1024 || this.#pendingBytes + bytes > limit) {
|
|
79
|
+
this.#droppedRecords += 1;
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
if (key !== undefined) this.#pendingCritical.add(key);
|
|
83
|
+
this.#pending.push({ record, bytes, ...(key === undefined ? {} : { key }) });
|
|
84
|
+
this.#pendingBytes += bytes;
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
#finishFlush(): void {
|
|
89
|
+
this.#resolveFlush?.();
|
|
90
|
+
this.#resolveFlush = null;
|
|
91
|
+
this.#flushPromise = null;
|
|
52
92
|
}
|
|
53
93
|
|
|
54
94
|
diagnostics(): Readonly<{
|
|
@@ -400,11 +400,12 @@ export class TerminalFastLaneRendererAdapter implements PaneScopedTerminalAdapte
|
|
|
400
400
|
identity.acceptedRevision,
|
|
401
401
|
]);
|
|
402
402
|
if (seen.has(key)) continue;
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
403
|
+
// Bound retained de-duplication history, not the renderer's lifetime.
|
|
404
|
+
// An evicted identity may be reported again only after another real paint.
|
|
405
|
+
// Pending identities still have their separate per-frame admission limit.
|
|
406
|
+
if (seen.size >= 256) seen.delete(seen.values().next().value!);
|
|
407
|
+
seen.add(key);
|
|
408
|
+
identities.push(identity);
|
|
408
409
|
}
|
|
409
410
|
const dropped = this.#droppedCanonicalHostFrames;
|
|
410
411
|
this.#droppedCanonicalHostFrames = 0;
|
|
@@ -28,6 +28,8 @@ export interface OpenTuiTerminalResourceSampler {
|
|
|
28
28
|
dispose(): void;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
// Limit outstanding low-water sampling chains, not completed observations over
|
|
32
|
+
// the lifetime of a renderer. Each chain owns at most one pending timeout.
|
|
31
33
|
const TERMINAL_RESOURCE_SAMPLE_LIMIT = 512;
|
|
32
34
|
// The ProductRig idle proof reads after 10.1s. Emit just before that boundary
|
|
33
35
|
// so the operation-scoped sample cannot race the proof read.
|
|
@@ -315,8 +317,7 @@ function createOpenTuiTerminalResourceSampler(
|
|
|
315
317
|
}[];
|
|
316
318
|
}>,
|
|
317
319
|
) => {
|
|
318
|
-
if (disposed || resourceEpochIdentity === null
|
|
319
|
-
return;
|
|
320
|
+
if (disposed || resourceEpochIdentity === null) return;
|
|
320
321
|
ordinal += 1;
|
|
321
322
|
const now = readDiagnosticNow();
|
|
322
323
|
if (now === null) return;
|
|
@@ -474,7 +475,11 @@ function createOpenTuiTerminalResourceSampler(
|
|
|
474
475
|
};
|
|
475
476
|
return {
|
|
476
477
|
afterFence(identity) {
|
|
477
|
-
if (disposed
|
|
478
|
+
if (disposed) return;
|
|
479
|
+
if (pending.size >= TERMINAL_RESOURCE_SAMPLE_LIMIT) {
|
|
480
|
+
recordSamplingFailure();
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
478
483
|
latestIdentity = identity;
|
|
479
484
|
let now: number | null;
|
|
480
485
|
if (resourceEpochIdentity === null) {
|
|
@@ -52,3 +52,35 @@ function graphemes(text: string): string[] {
|
|
|
52
52
|
);
|
|
53
53
|
return [...text];
|
|
54
54
|
}
|
|
55
|
+
|
|
56
|
+
/** PURE — greedy word-wrap for terminal prose (never returns empty for
|
|
57
|
+
* non-empty text; words longer than the width hard-break). */
|
|
58
|
+
export function wrapText(text: string, width: number): string[] {
|
|
59
|
+
if (width <= 0) return [text];
|
|
60
|
+
const out: string[] = [];
|
|
61
|
+
for (const para of text.split("\n")) {
|
|
62
|
+
let line = "";
|
|
63
|
+
for (const word of para.split(/\s+/).filter(Boolean)) {
|
|
64
|
+
if (line.length === 0) {
|
|
65
|
+
let w = word;
|
|
66
|
+
while (w.length > width) {
|
|
67
|
+
out.push(w.slice(0, width));
|
|
68
|
+
w = w.slice(width);
|
|
69
|
+
}
|
|
70
|
+
line = w;
|
|
71
|
+
} else if (line.length + 1 + word.length <= width) {
|
|
72
|
+
line += ` ${word}`;
|
|
73
|
+
} else {
|
|
74
|
+
out.push(line);
|
|
75
|
+
let w = word;
|
|
76
|
+
while (w.length > width) {
|
|
77
|
+
out.push(w.slice(0, width));
|
|
78
|
+
w = w.slice(width);
|
|
79
|
+
}
|
|
80
|
+
line = w;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (line.length > 0 || para.length === 0) out.push(line);
|
|
84
|
+
}
|
|
85
|
+
return out.length > 0 ? out : [""];
|
|
86
|
+
}
|
|
@@ -167,9 +167,12 @@ export function createApplicationConnectionFeedback(
|
|
|
167
167
|
failure,
|
|
168
168
|
...(inventory
|
|
169
169
|
? {
|
|
170
|
-
recovery:
|
|
171
|
-
|
|
172
|
-
|
|
170
|
+
recovery:
|
|
171
|
+
failure.reason === "duplicate-runtime-pane-binding"
|
|
172
|
+
? "A terminal is shared by multiple workspace entries. Unlink shared tmux windows so each belongs to one session, then select Retry."
|
|
173
|
+
: missing
|
|
174
|
+
? "A registered session may have been recreated. Choose that session to restore its identity, then retry here. It may be a different session."
|
|
175
|
+
: "Terminal identities conflict or cannot be verified. Copy connection details for diagnosis; Retry does not repair identity conflicts.",
|
|
173
176
|
}
|
|
174
177
|
: {}),
|
|
175
178
|
};
|
|
@@ -5,6 +5,9 @@ export type FleetConnectionFailureCode =
|
|
|
5
5
|
| "invalid-target"
|
|
6
6
|
| "invalid-descriptor"
|
|
7
7
|
| "incompatible"
|
|
8
|
+
| "ssh-authentication"
|
|
9
|
+
| "ssh-host-key"
|
|
10
|
+
| "remote-cli-missing"
|
|
8
11
|
| "daemon-missing";
|
|
9
12
|
|
|
10
13
|
export interface FleetConnectionStatus {
|
|
@@ -26,7 +29,13 @@ export function fleetConnectionMessage(status: FleetConnectionStatus): string {
|
|
|
26
29
|
case "invalid-descriptor":
|
|
27
30
|
return "Remote daemon discovery returned an invalid response. Check the installation.";
|
|
28
31
|
case "daemon-missing":
|
|
29
|
-
return "No running daemon.
|
|
32
|
+
return "No running daemon. Retrying automatically; start tmux-ide on this machine if needed.";
|
|
33
|
+
case "ssh-authentication":
|
|
34
|
+
return "SSH authentication failed. Check the machine's SSH credentials, then retry.";
|
|
35
|
+
case "ssh-host-key":
|
|
36
|
+
return "SSH host key verification failed. Verify the host in your terminal, then retry.";
|
|
37
|
+
case "remote-cli-missing":
|
|
38
|
+
return "Remote tmux-ide command not found. Check its installation and non-interactive SSH PATH.";
|
|
30
39
|
case "unavailable":
|
|
31
40
|
return "Connection failed. Check reachability, SSH authentication and host trust.";
|
|
32
41
|
default:
|
|
@@ -1257,7 +1257,10 @@ export function createWorkspaceClient<
|
|
|
1257
1257
|
startApplicationShell();
|
|
1258
1258
|
if (authorityShell !== null) {
|
|
1259
1259
|
if (!shellMatchesTerminalAuthority(authorityShell, resource))
|
|
1260
|
-
|
|
1260
|
+
// A newer terminal revision has already established topology. Read
|
|
1261
|
+
// its presentation/refusal details instead of refreshing that same
|
|
1262
|
+
// terminal revision again while leaving the shell stale.
|
|
1263
|
+
shellSession?.refresh();
|
|
1261
1264
|
}
|
|
1262
1265
|
return true;
|
|
1263
1266
|
},
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { ActionContractsZ } from "../actions-contract.ts";
|
|
3
|
-
|
|
4
|
-
describe("daemon action contract", () => {
|
|
5
|
-
it("supports generation-pinned cooperative shutdown", () => {
|
|
6
|
-
const instanceId = "9bcf33b0-c837-4a94-b5e8-c0977f54464f";
|
|
7
|
-
|
|
8
|
-
expect(
|
|
9
|
-
ActionContractsZ["daemon.shutdown"].input.parse({
|
|
10
|
-
reason: "takeover",
|
|
11
|
-
expectedInstanceId: instanceId,
|
|
12
|
-
}),
|
|
13
|
-
).toEqual({ reason: "takeover", expectedInstanceId: instanceId });
|
|
14
|
-
expect(
|
|
15
|
-
ActionContractsZ["daemon.shutdown"].input.safeParse({
|
|
16
|
-
expectedInstanceId: "not-a-uuid",
|
|
17
|
-
}).success,
|
|
18
|
-
).toBe(false);
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it("accepts only renderer-safe semantic workspace pane creation", () => {
|
|
22
|
-
const input = { kind: "terminal", workspaceName: "workspace.alpha" } as const;
|
|
23
|
-
expect(ActionContractsZ["workspace.pane.create"].input.parse(input)).toEqual(input);
|
|
24
|
-
for (const [field, value] of [
|
|
25
|
-
["cwd", "/tmp/project"],
|
|
26
|
-
["argv", ["sh", "-c", "owned"]],
|
|
27
|
-
["env", { SECRET: "renderer" }],
|
|
28
|
-
["paneId", "%42"],
|
|
29
|
-
["sessionName", "runtime-session"],
|
|
30
|
-
] as const) {
|
|
31
|
-
expect(
|
|
32
|
-
ActionContractsZ["workspace.pane.create"].input.safeParse({
|
|
33
|
-
...input,
|
|
34
|
-
[field]: value,
|
|
35
|
-
}).success,
|
|
36
|
-
).toBe(false);
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it("renames panes through semantic identity only", () => {
|
|
41
|
-
const input = {
|
|
42
|
-
workspaceName: "workspace.alpha",
|
|
43
|
-
scope: "pane",
|
|
44
|
-
semanticPaneId: "pane.main",
|
|
45
|
-
name: "Build monitor",
|
|
46
|
-
} as const;
|
|
47
|
-
expect(ActionContractsZ["workspace.rename"].input.parse(input)).toEqual(input);
|
|
48
|
-
expect(
|
|
49
|
-
ActionContractsZ["workspace.rename"].input.safeParse({
|
|
50
|
-
...input,
|
|
51
|
-
semanticPaneId: "%42",
|
|
52
|
-
}).success,
|
|
53
|
-
).toBe(false);
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it("keeps config-free workspace admission semantic and its result browser-safe", () => {
|
|
57
|
-
expect(ActionContractsZ["workspace.open"].input.parse({ projectDir: "/tmp/project" })).toEqual({
|
|
58
|
-
projectDir: "/tmp/project",
|
|
59
|
-
});
|
|
60
|
-
for (const [field, value] of [
|
|
61
|
-
["sessionName", "renderer-session"],
|
|
62
|
-
["paneId", "%42"],
|
|
63
|
-
["command", ["sh", "-c", "owned"]],
|
|
64
|
-
["env", { SECRET: "renderer" }],
|
|
65
|
-
] as const) {
|
|
66
|
-
expect(
|
|
67
|
-
ActionContractsZ["workspace.open"].input.safeParse({
|
|
68
|
-
projectDir: "/tmp/project",
|
|
69
|
-
[field]: value,
|
|
70
|
-
}).success,
|
|
71
|
-
).toBe(false);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const result = ActionContractsZ["workspace.open"].result.parse({
|
|
75
|
-
operationId: "10000000-0000-4000-8000-000000000001",
|
|
76
|
-
daemonInstanceId: "20000000-0000-4000-8000-000000000002",
|
|
77
|
-
outcome: "created",
|
|
78
|
-
resource: {
|
|
79
|
-
resourceVersion: 1,
|
|
80
|
-
workspaceName: "project-00112233445566778899aabbccddeeff",
|
|
81
|
-
initialPaneId: "pane.workspace.00112233445566778899aabbccddeeff",
|
|
82
|
-
},
|
|
83
|
-
});
|
|
84
|
-
expect(JSON.stringify(result)).not.toMatch(/projectDir|sessionName|runtime|tmux|path/u);
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it("lets the trusted desktop host select a folder without exposing its path", () => {
|
|
88
|
-
const input = {
|
|
89
|
-
source: { kind: "host-selection" },
|
|
90
|
-
previousWorkspaceName: "workspace.alpha",
|
|
91
|
-
} as const;
|
|
92
|
-
expect(ActionContractsZ["workspace.open.prepare"].input.parse(input)).toEqual(input);
|
|
93
|
-
expect(
|
|
94
|
-
ActionContractsZ["workspace.open.prepare"].input.safeParse({
|
|
95
|
-
...input,
|
|
96
|
-
source: { kind: "host-selection", projectDir: "/private/project" },
|
|
97
|
-
}).success,
|
|
98
|
-
).toBe(false);
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it("accepts only semantic pane identities for a swap", () => {
|
|
102
|
-
const input = {
|
|
103
|
-
workspaceName: "workspace.alpha",
|
|
104
|
-
sourceSemanticPaneId: "pane.source",
|
|
105
|
-
targetSemanticPaneId: "pane.target",
|
|
106
|
-
} as const;
|
|
107
|
-
expect(ActionContractsZ["workspace.pane.swap"].input.parse(input)).toEqual(input);
|
|
108
|
-
for (const unsafe of [
|
|
109
|
-
{ sourcePaneId: "%1" },
|
|
110
|
-
{ targetPaneId: "%2" },
|
|
111
|
-
{ tmuxCommand: "swap-pane -D" },
|
|
112
|
-
{ sessionName: "runtime-session" },
|
|
113
|
-
]) {
|
|
114
|
-
expect(
|
|
115
|
-
ActionContractsZ["workspace.pane.swap"].input.safeParse({ ...input, ...unsafe }).success,
|
|
116
|
-
).toBe(false);
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
});
|