tmux-ide 2.9.2 → 2.9.4
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/LICENSE +1 -1
- package/README.md +121 -140
- package/bin/cli.js +2457 -727
- package/package.json +23 -8
- 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/integrations/claude-agent-teams.js +264 -0
- 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/integrations/claude-agent-teams.ts +334 -0
- 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/skill/SKILL.md +30 -30
- 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
|
},
|
package/skill/SKILL.md
CHANGED
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- tmux-ide-skill-version: 2.6.0 -->
|
|
4
4
|
|
|
5
|
-
tmux-ide is
|
|
6
|
-
|
|
7
|
-
working/blocked/done
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
tmux-ide is **the open-source workspace for coding agents**, built on tmux. The
|
|
6
|
+
app (`tmux-ide app`) shows every agent across local and SSH machines with
|
|
7
|
+
ground-truth working/blocked/done status, and drives the live tmux session.
|
|
8
|
+
`tmux-ide adopt` adds the same status to plain tmux clients as tmux chrome: a
|
|
9
|
+
status bar, keys and menus, all additive tmux options with no wrapper process.
|
|
10
|
+
Around both: notifications when an agent needs a human, and crash-proof restore.
|
|
11
|
+
tmux owns every process and pane, so sessions survive tmux-ide. `.tmux-ide/workspace.yml`
|
|
12
|
+
is optional.
|
|
11
13
|
|
|
12
14
|
## When to use
|
|
13
15
|
|
|
@@ -206,30 +208,28 @@ Right-click any pane or the bar opens the actions menu at the pointer.
|
|
|
206
208
|
| Panels — explorer / changes / config | `prefix e` `g` `v` | `⌥e` `⌥g` `⌥,` |
|
|
207
209
|
|
|
208
210
|
One interaction grammar everywhere: `j`/`k` move, `enter` opens, `/` filters,
|
|
209
|
-
`esc` backs out, `?` asks. Bare `tmux-ide` with no project config opens the
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
## The app — `tmux-ide app`
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
- State persists across launches (~/.tmux-ide/app-state.json): last tab,
|
|
232
|
-
session, open file.
|
|
211
|
+
`esc` backs out, `?` asks. Bare `tmux-ide` with no project config opens the
|
|
212
|
+
**app** (below). `tmux-ide cheatsheet` prints the full sheet.
|
|
213
|
+
|
|
214
|
+
## The app — `tmux-ide app`
|
|
215
|
+
|
|
216
|
+
The full-screen app: tmux stays the engine (PTYs, agents, persistence); the app
|
|
217
|
+
renders it. Launch `tmux-ide app` (Home) or `tmux-ide app <session>`. Installed
|
|
218
|
+
releases include the runtime; `tmux-ide update --tui-binary` re-downloads it.
|
|
219
|
+
|
|
220
|
+
- **Two surfaces**: `F1` Home (agents across local + SSH machines; `/` search,
|
|
221
|
+
`f` machine filter, `0`/`w`/`a` All/Working/Needs attention, `Enter` opens the
|
|
222
|
+
agent's pane) and `F2` Terminals (the session mirrored live, window tabs, pane
|
|
223
|
+
headers with agent state). There are no Files/Diff/Missions views in 2.9, and
|
|
224
|
+
`app.views` in workspace.yml is validated but not read.
|
|
225
|
+
- **Overlays**: `F5` Commands (new window, New agent…, splits, zoom, Appearance…,
|
|
226
|
+
help) · `F6` Sessions · `F7` Attention · `F8`/`F9` session history/tabs ·
|
|
227
|
+
`F10` sidebar · `Ctrl+G` focus sidebar. `Ctrl+K` in Commands lists every key.
|
|
228
|
+
- **Terminals**: `Ctrl+O`/`Ctrl+T` next pane/window, `Alt+Arrow` resize, drag
|
|
229
|
+
borders; right-click a pane for select text / rename / split / zoom / close
|
|
230
|
+
(confirmed). Shift+click opens links; Shift+drag selects inside mouse apps.
|
|
231
|
+
- `Ctrl+Q` quits — sessions keep running. `tmux-ide app --detachable` hosts the
|
|
232
|
+
app in tmux so `Ctrl+Q` detaches instead.
|
|
233
233
|
|
|
234
234
|
## .tmux-ide/workspace.yml (optional)
|
|
235
235
|
|
|
@@ -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
|
-
});
|