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.
Files changed (263) hide show
  1. package/README.md +1 -1
  2. package/bin/cli.js +2071 -625
  3. package/package.json +14 -5
  4. package/packages/contracts/src/desktop-host.ts +3 -0
  5. package/packages/contracts/src/saved-machines.ts +19 -0
  6. package/packages/contracts/src/terminal-replica.ts +1 -1
  7. package/packages/core/package.json +3 -2
  8. package/packages/core/src/terminal-delivery.ts +51 -3
  9. package/packages/core/src/terminal-fnv64-wasm.ts +4 -3
  10. package/packages/core/src/terminal-replica-hash-cache.ts +129 -31
  11. package/packages/core/src/terminal-replica-owned-row.ts +27 -0
  12. package/packages/core/src/terminal-replica.ts +13 -28
  13. package/packages/daemon/dist/command-center/daemon-fleet-facts-observer.js +96 -10
  14. package/packages/daemon/dist/command-center/resources/saved-machine-route.js +40 -1
  15. package/packages/daemon/dist/command-center/ws-events.js +5 -24
  16. package/packages/daemon/dist/lib/canonical-daemon-bootstrap.js +8 -0
  17. package/packages/daemon/dist/lib/canonical-daemon.js +28 -2
  18. package/packages/daemon/dist/lib/daemon-embed.js +1 -1
  19. package/packages/daemon/dist/lib/daemon-service-manager.js +122 -0
  20. package/packages/daemon/dist/lib/daemon-service-plan.js +127 -0
  21. package/packages/daemon/dist/lib/daemon-service.js +259 -0
  22. package/packages/daemon/dist/lib/install-origin.js +2 -0
  23. package/packages/daemon/dist/lib/local-fleet-request.js +9 -3
  24. package/packages/daemon/dist/lib/log.js +6 -10
  25. package/packages/daemon/dist/lib/managed-installer-update.js +67 -0
  26. package/packages/daemon/dist/lib/{tui-download-lock.js → private-operation-lock.js} +11 -11
  27. package/packages/daemon/dist/lib/remote-daemon-info.js +3 -2
  28. package/packages/daemon/dist/lib/remote-daemon-lifecycle.js +4 -4
  29. package/packages/daemon/dist/lib/remote-tmux-command.js +10 -0
  30. package/packages/daemon/dist/lib/runtime-namespace.js +28 -16
  31. package/packages/daemon/dist/lib/saved-machines.js +40 -2
  32. package/packages/daemon/dist/lib/ssh-daemon-transport.js +24 -9
  33. package/packages/daemon/dist/lib/tmux-server-owner.js +1 -1
  34. package/packages/daemon/dist/lib/tmux-server-registration.js +21 -3
  35. package/packages/daemon/dist/lib/tui-binary.js +2 -2
  36. package/packages/daemon/dist/lib/update.js +18 -0
  37. package/packages/daemon/dist/lib/workspace-multiplexer-verbs.js +24 -1
  38. package/packages/daemon/dist/machines.js +40 -4
  39. package/packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/Info.plist +2 -2
  40. package/packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/MacOS/tmux-ide-notifier +0 -0
  41. package/packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/Resources/Assets.car +0 -0
  42. package/packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/_CodeSignature/CodeResources +2 -2
  43. package/packages/daemon/dist/terminal/attachments/direct-websocket.js +4 -1
  44. package/packages/daemon/dist/terminal/attachments/native-runtime.js +22 -13
  45. package/packages/daemon/dist/terminal/mirror/mirror-service.js +101 -3
  46. package/packages/daemon/dist/terminal/mirror/registered-window-guard.js +62 -0
  47. package/packages/daemon/dist/terminal/mirror/session-channel.js +75 -4
  48. package/packages/daemon/dist/terminal/mirror/shared-window-index.js +45 -0
  49. package/packages/daemon/dist/terminal/pane-stream/pane-stream-websocket.js +11 -1
  50. package/packages/daemon/dist/terminal/session-runtime/multiplexer-backend.js +1 -0
  51. package/packages/daemon/dist/terminal/session-runtime/registry.js +56 -7
  52. package/packages/daemon/dist/terminal/session-runtime/semantic-mutation-executor.js +3 -1
  53. package/packages/daemon/dist/tui/mirror/dialog-model.js +2 -35
  54. package/packages/daemon/dist/tui/mirror/runtime/application-daemon-authority-owner.js +8 -0
  55. package/packages/daemon/dist/tui/mirror/runtime/application-home-fleet.js +20 -2
  56. package/packages/daemon/dist/tui/mirror/runtime/application-machine-agents.js +7 -1
  57. package/packages/daemon/dist/tui/mirror/runtime/application-machine-authority.js +59 -9
  58. package/packages/daemon/dist/tui/mirror/runtime/application-machine-navigation.js +27 -19
  59. package/packages/daemon/dist/tui/mirror/runtime/application-machine-sidebar.jsx +23 -18
  60. package/packages/daemon/dist/tui/mirror/runtime/application-machine-startup.js +31 -2
  61. package/packages/daemon/dist/tui/mirror/runtime/application-palette-search-owner.js +7 -3
  62. package/packages/daemon/dist/tui/mirror/runtime/application-performance-log.js +3 -0
  63. package/packages/daemon/dist/tui/mirror/runtime/application-terminal-input-ingress.js +146 -2
  64. package/packages/daemon/dist/tui/mirror/runtime/application-terminal-interaction-controller.js +201 -50
  65. package/packages/daemon/dist/tui/mirror/runtime/bounded-performance-record-writer.js +50 -10
  66. package/packages/daemon/dist/tui/mirror/runtime/terminal-fast-lane-renderer-adapter.js +6 -5
  67. package/packages/daemon/dist/tui/mirror/runtime/terminal-pane-input-router.js +3 -0
  68. package/packages/daemon/dist/tui/mirror/runtime/workspace-terminal-fast-lane.js +8 -2
  69. package/packages/daemon/dist/tui/mirror/terminal-text.js +35 -0
  70. package/packages/daemon/dist/tui/mirror/workspace/connection-feedback.js +5 -3
  71. package/packages/daemon/src/command-center/daemon-fleet-facts-observer.ts +100 -10
  72. package/packages/daemon/src/command-center/resources/saved-machine-route.ts +48 -1
  73. package/packages/daemon/src/command-center/ws-events.ts +5 -25
  74. package/packages/daemon/src/lib/canonical-daemon-bootstrap.ts +12 -0
  75. package/packages/daemon/src/lib/canonical-daemon.ts +44 -2
  76. package/packages/daemon/src/lib/daemon-embed.ts +1 -0
  77. package/packages/daemon/src/lib/daemon-service-manager.ts +152 -0
  78. package/packages/daemon/src/lib/daemon-service-plan.ts +153 -0
  79. package/packages/daemon/src/lib/daemon-service.ts +301 -0
  80. package/packages/daemon/src/lib/install-origin.ts +5 -0
  81. package/packages/daemon/src/lib/local-fleet-request.ts +19 -3
  82. package/packages/daemon/src/lib/log.ts +13 -9
  83. package/packages/daemon/src/lib/managed-installer-update.ts +79 -0
  84. package/packages/daemon/src/lib/{tui-download-lock.ts → private-operation-lock.ts} +15 -11
  85. package/packages/daemon/src/lib/remote-daemon-info.ts +3 -3
  86. package/packages/daemon/src/lib/remote-daemon-lifecycle.ts +4 -4
  87. package/packages/daemon/src/lib/remote-tmux-command.ts +12 -0
  88. package/packages/daemon/src/lib/runtime-namespace.ts +27 -18
  89. package/packages/daemon/src/lib/saved-machines.ts +40 -1
  90. package/packages/daemon/src/lib/ssh-daemon-transport.ts +25 -7
  91. package/packages/daemon/src/lib/tmux-server-owner.ts +1 -0
  92. package/packages/daemon/src/lib/tmux-server-registration.ts +21 -3
  93. package/packages/daemon/src/lib/tui-binary.ts +2 -2
  94. package/packages/daemon/src/lib/update.ts +24 -0
  95. package/packages/daemon/src/lib/workspace-multiplexer-verbs.ts +22 -0
  96. package/packages/daemon/src/machines.ts +53 -5
  97. package/packages/daemon/src/terminal/attachments/direct-websocket.ts +8 -2
  98. package/packages/daemon/src/terminal/attachments/native-runtime.ts +28 -13
  99. package/packages/daemon/src/terminal/mirror/mirror-service.ts +105 -3
  100. package/packages/daemon/src/terminal/mirror/registered-window-guard.ts +66 -0
  101. package/packages/daemon/src/terminal/mirror/session-channel.ts +92 -4
  102. package/packages/daemon/src/terminal/mirror/shared-window-index.ts +42 -0
  103. package/packages/daemon/src/terminal/pane-stream/pane-stream-websocket.ts +12 -1
  104. package/packages/daemon/src/terminal/session-runtime/multiplexer-backend.ts +2 -0
  105. package/packages/daemon/src/terminal/session-runtime/registry.ts +70 -8
  106. package/packages/daemon/src/terminal/session-runtime/semantic-mutation-executor.ts +3 -1
  107. package/packages/daemon/src/tui/mirror/dialog-model.ts +2 -32
  108. package/packages/daemon/src/tui/mirror/runtime/application-daemon-authority-owner.ts +8 -0
  109. package/packages/daemon/src/tui/mirror/runtime/application-home-fleet.ts +19 -2
  110. package/packages/daemon/src/tui/mirror/runtime/application-machine-agents.ts +6 -1
  111. package/packages/daemon/src/tui/mirror/runtime/application-machine-authority.ts +60 -11
  112. package/packages/daemon/src/tui/mirror/runtime/application-machine-navigation.ts +39 -33
  113. package/packages/daemon/src/tui/mirror/runtime/application-machine-sidebar.tsx +31 -23
  114. package/packages/daemon/src/tui/mirror/runtime/application-machine-startup.ts +38 -2
  115. package/packages/daemon/src/tui/mirror/runtime/application-palette-search-owner.ts +7 -4
  116. package/packages/daemon/src/tui/mirror/runtime/application-performance-log.ts +3 -0
  117. package/packages/daemon/src/tui/mirror/runtime/application-root-v2.tsx +1 -1
  118. package/packages/daemon/src/tui/mirror/runtime/application-shell-view.tsx +47 -46
  119. package/packages/daemon/src/tui/mirror/runtime/application-terminal-input-ingress.ts +165 -2
  120. package/packages/daemon/src/tui/mirror/runtime/application-terminal-interaction-controller.ts +207 -53
  121. package/packages/daemon/src/tui/mirror/runtime/bounded-performance-record-writer.ts +49 -9
  122. package/packages/daemon/src/tui/mirror/runtime/terminal-fast-lane-renderer-adapter.ts +6 -5
  123. package/packages/daemon/src/tui/mirror/runtime/terminal-pane-input-router.ts +4 -0
  124. package/packages/daemon/src/tui/mirror/runtime/workspace-terminal-fast-lane.ts +8 -3
  125. package/packages/daemon/src/tui/mirror/terminal-text.ts +32 -0
  126. package/packages/daemon/src/tui/mirror/workspace/connection-feedback.ts +6 -3
  127. package/packages/daemon-client/src/fleet-connection-status.ts +10 -1
  128. package/packages/daemon-client/src/workspace-client.ts +4 -1
  129. package/packages/contracts/src/__tests__/actions-contract.test.ts +0 -119
  130. package/packages/contracts/src/__tests__/agent-graph-overlay.test.ts +0 -428
  131. package/packages/contracts/src/__tests__/app-window-mutation.test.ts +0 -51
  132. package/packages/contracts/src/__tests__/app-window-state.test.ts +0 -34
  133. package/packages/contracts/src/__tests__/application-shell.test.ts +0 -645
  134. package/packages/contracts/src/__tests__/automation-operations.test.ts +0 -78
  135. package/packages/contracts/src/__tests__/causal-cell.test.ts +0 -47
  136. package/packages/contracts/src/__tests__/client-view-state.test.ts +0 -115
  137. package/packages/contracts/src/__tests__/cohesion-fixture.test.ts +0 -106
  138. package/packages/contracts/src/__tests__/commands.test.ts +0 -86
  139. package/packages/contracts/src/__tests__/control.test.ts +0 -154
  140. package/packages/contracts/src/__tests__/daemon-events.test.ts +0 -405
  141. package/packages/contracts/src/__tests__/daemon-resources.test.ts +0 -143
  142. package/packages/contracts/src/__tests__/daemon-wire.test.ts +0 -149
  143. package/packages/contracts/src/__tests__/desktop-host.test.ts +0 -269
  144. package/packages/contracts/src/__tests__/desktop-missions.test.ts +0 -215
  145. package/packages/contracts/src/__tests__/experience-conformance.test.ts +0 -153
  146. package/packages/contracts/src/__tests__/experience-kernel-boundary.test.ts +0 -113
  147. package/packages/contracts/src/__tests__/experience-shell.test.ts +0 -65
  148. package/packages/contracts/src/__tests__/fixtures/daemon-wire-v2.json +0 -35
  149. package/packages/contracts/src/__tests__/fixtures/daemon-wire-v3.json +0 -35
  150. package/packages/contracts/src/__tests__/fixtures/daemon-wire-v4.json +0 -35
  151. package/packages/contracts/src/__tests__/fixtures/scoped-receipt.ts +0 -62
  152. package/packages/contracts/src/__tests__/fleet-agent-graph.test.ts +0 -231
  153. package/packages/contracts/src/__tests__/fleet-catalog.test.ts +0 -270
  154. package/packages/contracts/src/__tests__/fleet-lifecycle.test.ts +0 -62
  155. package/packages/contracts/src/__tests__/focus-overlay.test.ts +0 -110
  156. package/packages/contracts/src/__tests__/ide-config.test.ts +0 -64
  157. package/packages/contracts/src/__tests__/interaction-evidence.test.ts +0 -288
  158. package/packages/contracts/src/__tests__/interaction-receipt-v2.test.ts +0 -72
  159. package/packages/contracts/src/__tests__/issue-error.test.ts +0 -78
  160. package/packages/contracts/src/__tests__/mission-projections.test.ts +0 -186
  161. package/packages/contracts/src/__tests__/missions.test.ts +0 -272
  162. package/packages/contracts/src/__tests__/multiplexer-verbs.test.ts +0 -242
  163. package/packages/contracts/src/__tests__/pane-appearance.test.ts +0 -146
  164. package/packages/contracts/src/__tests__/pane-read-result.test.ts +0 -55
  165. package/packages/contracts/src/__tests__/pane-stream.test.ts +0 -536
  166. package/packages/contracts/src/__tests__/pane-widget-marker.test.ts +0 -327
  167. package/packages/contracts/src/__tests__/performance-metrics.test.ts +0 -73
  168. package/packages/contracts/src/__tests__/performance-qualification.test.ts +0 -137
  169. package/packages/contracts/src/__tests__/rich-card-widget.test.ts +0 -29
  170. package/packages/contracts/src/__tests__/session-runtime.test.ts +0 -512
  171. package/packages/contracts/src/__tests__/startup-readiness.test.ts +0 -409
  172. package/packages/contracts/src/__tests__/terminal-attachment-stream.test.ts +0 -72
  173. package/packages/contracts/src/__tests__/terminal-attachments.test.ts +0 -329
  174. package/packages/contracts/src/__tests__/terminal-delivery.test.ts +0 -88
  175. package/packages/contracts/src/__tests__/terminal-runtime-inventory.test.ts +0 -68
  176. package/packages/contracts/src/__tests__/terminals.test.ts +0 -87
  177. package/packages/contracts/src/__tests__/tmux-server-scope.test.ts +0 -166
  178. package/packages/contracts/src/__tests__/transport-contract-loading.test.ts +0 -91
  179. package/packages/contracts/src/__tests__/visual-tokens.test.ts +0 -224
  180. package/packages/contracts/src/__tests__/window-links.test.ts +0 -243
  181. package/packages/contracts/src/__tests__/workspace-changes-resource.test.ts +0 -317
  182. package/packages/contracts/src/__tests__/workspace-changes-view.test.ts +0 -122
  183. package/packages/contracts/src/__tests__/workspace-config.test.ts +0 -294
  184. package/packages/contracts/src/__tests__/workspace-files-resource.test.ts +0 -261
  185. package/packages/contracts/src/__tests__/workspace-files-tree.test.ts +0 -147
  186. package/packages/contracts/src/__tests__/workspace-pane-creation.test.ts +0 -249
  187. package/packages/contracts/src/__tests__/workspace-promotion.test.ts +0 -94
  188. package/packages/contracts/src/__tests__/workspace-resource-identity.test.ts +0 -90
  189. package/packages/contracts/src/daemon-resource-request.test.ts +0 -192
  190. package/packages/contracts/src/native-operation-identity.test.ts +0 -23
  191. package/packages/contracts/src/workspace-admission.test.ts +0 -21
  192. package/packages/contracts/src/workspace-catalog-resource.test.ts +0 -146
  193. package/packages/core/src/agent-provisioning.test.ts +0 -42
  194. package/packages/core/src/application-shell-session.test.ts +0 -105
  195. package/packages/core/src/interaction-evidence.test.ts +0 -134
  196. package/packages/core/src/interaction-flow.test.ts +0 -66
  197. package/packages/core/src/interaction-receipts.test.ts +0 -671
  198. package/packages/core/src/navigator.test.ts +0 -34
  199. package/packages/core/src/optimistic-projection-conformance.test.ts +0 -75
  200. package/packages/core/src/optimistic-projection.test.ts +0 -118
  201. package/packages/core/src/performance-metrics.test.ts +0 -121
  202. package/packages/core/src/performance-qualification.test.ts +0 -283
  203. package/packages/core/src/saved-machines.test.ts +0 -80
  204. package/packages/core/src/terminal-compact-cold.test.ts +0 -87
  205. package/packages/core/src/terminal-conformance.test.ts +0 -48
  206. package/packages/core/src/terminal-delivery-cache-lifetime.test.ts +0 -167
  207. package/packages/core/src/terminal-delivery-encode-cooperative.test.ts +0 -140
  208. package/packages/core/src/terminal-delivery-representation-hash.test.ts +0 -77
  209. package/packages/core/src/terminal-delivery.test.ts +0 -1471
  210. package/packages/core/src/terminal-fnv64-wasm.test.ts +0 -61
  211. package/packages/core/src/terminal-replica-cold.test.ts +0 -31
  212. package/packages/core/src/terminal-replica-cooperative.test.ts +0 -170
  213. package/packages/core/src/terminal-replica-hash-cache.test.ts +0 -283
  214. package/packages/core/src/terminal-replica.test.ts +0 -347
  215. package/packages/core/src/workspace-selection.test.ts +0 -63
  216. package/packages/daemon/dist/__tests__/support.js +0 -33
  217. package/packages/daemon/dist/lib/__tests__/fixtures/workspace-state-writer.js +0 -58
  218. package/packages/daemon/dist/lib/__tests__/installed-recovery-fixture.js +0 -400
  219. package/packages/daemon/dist/terminal/__tests__/MockPtyAdapter.js +0 -182
  220. package/packages/daemon/dist/terminal/mirror/__tests__/scripted-channel.js +0 -98
  221. package/packages/daemon/dist/terminal/mirror/__tests__/simulated-channel.js +0 -156
  222. package/packages/daemon/src/tui/mirror/__snapshots__/activity-surface-renderer.test.tsx.snap +0 -42
  223. package/packages/daemon/src/tui/mirror/__snapshots__/changes-terminal-surface-renderer.test.tsx.snap +0 -267
  224. package/packages/daemon/src/tui/mirror/__snapshots__/home-files-surface-renderer.test.tsx.snap +0 -267
  225. package/packages/daemon/src/tui/mirror/__snapshots__/missions-surface-renderer.test.tsx.snap +0 -134
  226. package/packages/daemon/src/tui/mirror/__snapshots__/recipes-gallery-renderer.test.tsx.snap +0 -141
  227. package/packages/daemon/src/tui/mirror/__snapshots__/shell-chrome-renderer.test.tsx.snap +0 -134
  228. package/packages/daemon/src/tui/mirror/runtime/__snapshots__/application-shell-view-renderer.test.tsx.snap +0 -87
  229. package/packages/daemon/src/tui/mirror/workspace/__snapshots__/agent-terminal-canvas-renderer.test.tsx.snap +0 -348
  230. package/packages/daemon/src/tui/mirror/workspace/__snapshots__/application-shell-renderer.test.tsx.snap +0 -134
  231. package/packages/daemon/src/tui/mirror/workspace/__snapshots__/command-palette-surface-renderer.test.tsx.snap +0 -255
  232. package/packages/daemon/src/tui/mirror/workspace/__snapshots__/pane-frame-renderer.test.tsx.snap +0 -525
  233. package/packages/daemon/src/tui/mirror/workspace/__snapshots__/terminal-pane-header-polish-renderer.test.tsx.snap +0 -31
  234. package/packages/daemon/src/tui/mirror/workspace/__snapshots__/workbench-shell-renderer.test.tsx.snap +0 -134
  235. package/packages/daemon-client/src/application-shell-session.test.ts +0 -196
  236. package/packages/daemon-client/src/automation-client.test.ts +0 -214
  237. package/packages/daemon-client/src/bootstrap-coordinator.test.ts +0 -145
  238. package/packages/daemon-client/src/connection-supervisor.test.ts +0 -109
  239. package/packages/daemon-client/src/direct-application-shell-transport.test.ts +0 -941
  240. package/packages/daemon-client/src/first-latest-coordinator.test.ts +0 -175
  241. package/packages/daemon-client/src/fleet-dial-scheduler.test.ts +0 -114
  242. package/packages/daemon-client/src/fleet-environments.test.ts +0 -40
  243. package/packages/daemon-client/src/generation-bound-store-timers.test.ts +0 -74
  244. package/packages/daemon-client/src/owner-action-client.test.ts +0 -245
  245. package/packages/daemon-client/src/pane-stream-client.test.ts +0 -2841
  246. package/packages/daemon-client/src/pane-stream-clock-calibration.test.ts +0 -207
  247. package/packages/daemon-client/src/pane-stream-loopback-benchmark.test.ts +0 -51
  248. package/packages/daemon-client/src/push-resource-session.test.ts +0 -509
  249. package/packages/daemon-client/src/resource-replica.test.ts +0 -186
  250. package/packages/daemon-client/src/runtime-resource-ledger.test.ts +0 -18
  251. package/packages/daemon-client/src/scoped-tmux-server-transport.test.ts +0 -114
  252. package/packages/daemon-client/src/terminal-fast-lane.test.ts +0 -835
  253. package/packages/daemon-client/src/tmux-server-client.test.ts +0 -279
  254. package/packages/daemon-client/src/tmux-server-interaction-events.test.ts +0 -230
  255. package/packages/daemon-client/src/workspace-catalog-v2.test.ts +0 -109
  256. package/packages/daemon-client/src/workspace-client-boundaries.test.ts +0 -59
  257. package/packages/daemon-client/src/workspace-client-operations.test.ts +0 -96
  258. package/packages/daemon-client/src/workspace-client.test.ts +0 -2912
  259. package/packages/daemon-client/src/workspace-event-supervisor.test.ts +0 -1086
  260. package/packages/daemon-client/src/workspace-pane-client.test.ts +0 -80
  261. package/packages/presentation/src/presentation-contract.test.ts +0 -63
  262. package/packages/tmux-bridge/src/runner.test.ts +0 -614
  263. package/packages/tmux-bridge/src/targeting.test.ts +0 -107
@@ -1,671 +0,0 @@
1
- import {
2
- InteractionReceiptV1SchemaZ,
3
- InteractionReceiptV2SchemaZ,
4
- type InteractionReceipt,
5
- type InteractionJournalEntry,
6
- InteractionEvidenceRecordSchemaZ,
7
- } from "@tmux-ide/contracts";
8
- import { describe, expect, it } from "vitest";
9
-
10
- import {
11
- initialInteractionFeedState,
12
- interactionPaneEndpointKey,
13
- interactionForPane,
14
- interactionPresenceIsFresh,
15
- interactionReceiptLabel,
16
- paneInteractionPresence,
17
- paneInteractionRelationshipLabel,
18
- reduceInteractionReceipt as reduceReceipt,
19
- } from "./interaction-receipts.ts";
20
-
21
- function onlyReceipt(entry: InteractionJournalEntry | undefined): InteractionReceipt {
22
- if (!entry || entry.type !== "interaction.receipt") throw Error("Expected authored receipt");
23
- return entry;
24
- }
25
- const fixtureId = "00000000-0000-4000-8000-000000000001";
26
- function endpoint(semanticPaneId: string) {
27
- return {
28
- kind: "pane" as const,
29
- environmentId: fixtureId,
30
- serverScope: { serverId: `tmux-server.${"a".repeat(32)}`, generation: fixtureId },
31
- paneLifetimeId: fixtureId,
32
- workspaceName: "workspace.alpha",
33
- semanticPaneId,
34
- };
35
- }
36
- // These legacy behavior fixtures explicitly model a verified authored enqueue/snapshot.
37
- // Passive external records instead carry only stock command observation.
38
- function fixtureReceipt(raw: unknown): InteractionReceipt {
39
- const receipt = InteractionReceiptV1SchemaZ.parse(raw);
40
- const pane =
41
- receipt.operationKind === "workspace.pane.send" ||
42
- receipt.operationKind === "workspace.pane.read";
43
- const source = receipt.sourceSemanticPaneId ? endpoint(receipt.sourceSemanticPaneId) : null;
44
- return InteractionReceiptV2SchemaZ.parse({
45
- ...receipt,
46
- evidence: pane
47
- ? {
48
- schemaVersion: 1,
49
- interactionId: receipt.operationId,
50
- revision: receipt.phase === "accepted" ? 0 : 1,
51
- endpoints: {
52
- destination: {
53
- ...endpoint(
54
- receipt.target.kind === "pane" ? receipt.target.semanticPaneId : "pane.fixture",
55
- ),
56
- workspaceName: receipt.workspaceName,
57
- },
58
- source,
59
- },
60
- actor:
61
- receipt.origin === "external"
62
- ? { kind: "unknown", reason: "stock-hook" }
63
- : source
64
- ? { kind: "cooperative", bindingId: fixtureId, agentRunId: null }
65
- : { kind: "unknown", reason: "unbound-source" },
66
- observation:
67
- receipt.origin === "external"
68
- ? {
69
- kind: "stock-hook",
70
- command:
71
- receipt.operationKind === "workspace.pane.read" ? "capture-pane" : "send-keys",
72
- }
73
- : receipt.phase === "observed"
74
- ? {
75
- kind: "cooperative-completion",
76
- operationId: receipt.operationId,
77
- verification:
78
- receipt.operationKind === "workspace.pane.read"
79
- ? "daemon-snapshot"
80
- : "daemon-input-enqueue",
81
- }
82
- : { kind: "admission", operationId: receipt.operationId },
83
- effect:
84
- receipt.origin !== "external" && receipt.phase === "observed"
85
- ? {
86
- kind:
87
- receipt.operationKind === "workspace.pane.read"
88
- ? "snapshot-produced"
89
- : "input-enqueued",
90
- }
91
- : { kind: "unknown" },
92
- occurredAt: null,
93
- timeBasis: "unknown",
94
- receivedAt: receipt.at,
95
- }
96
- : null,
97
- });
98
- }
99
- function reduceFixtureReceipt(previous: Parameters<typeof reduceReceipt>[0], raw: unknown) {
100
- return reduceReceipt(previous, fixtureReceipt(raw));
101
- }
102
- function fixtureReceiptLabel(raw: unknown) {
103
- return interactionReceiptLabel(fixtureReceipt(raw));
104
- }
105
-
106
- const base = {
107
- type: "interaction.receipt" as const,
108
- operationId: "10000000-0000-4000-8000-000000000001",
109
- origin: "sdk" as const,
110
- workspaceName: "workspace.alpha",
111
- sourceSemanticPaneId: null,
112
- target: { kind: "pane" as const, semanticPaneId: "pane.alpha" },
113
- operationKind: "workspace.pane.send" as const,
114
- summary: {
115
- operationKind: "workspace.pane.send" as const,
116
- characterCount: 84,
117
- byteCount: 84,
118
- submitted: true,
119
- },
120
- proof: null,
121
- at: "2026-08-10T10:00:00.000Z",
122
- resourceRevision: null,
123
- };
124
-
125
- describe("interaction receipt reducer", () => {
126
- it("keeps replay history without reviving stale visual presence", () => {
127
- const now = Date.parse("2026-08-10T10:00:04.000Z");
128
- expect(interactionPresenceIsFresh({ at: "2026-08-10T10:00:02.000Z" }, now)).toBe(true);
129
- expect(interactionPresenceIsFresh({ at: "2026-08-10T09:59:59.000Z" }, now)).toBe(false);
130
- expect(interactionPresenceIsFresh({ at: "not-a-date" }, now)).toBe(false);
131
- });
132
- it("advances one operation in place and projects pane feedback", () => {
133
- const accepted = reduceFixtureReceipt(initialInteractionFeedState(), {
134
- ...base,
135
- sequence: 1,
136
- phase: "accepted",
137
- });
138
- const observed = reduceFixtureReceipt(accepted, {
139
- ...base,
140
- sequence: 2,
141
- phase: "observed",
142
- proof: {
143
- operationKind: "workspace.pane.send",
144
- observed: true,
145
- semanticPaneId: "pane.alpha",
146
- },
147
- });
148
-
149
- expect(observed.activity).toHaveLength(1);
150
- expect(onlyReceipt(observed.activity[0]).phase).toBe("observed");
151
- expect(interactionForPane(observed, endpoint("pane.alpha"))).toMatchObject({
152
- phase: "observed",
153
- label: "sdk observed · delivered 84 characters + Enter",
154
- });
155
- });
156
-
157
- it("ignores duplicate replay frames", () => {
158
- const current = reduceFixtureReceipt(initialInteractionFeedState(), {
159
- ...base,
160
- sequence: 3,
161
- phase: "observed",
162
- proof: {
163
- operationKind: "workspace.pane.send",
164
- observed: true,
165
- semanticPaneId: "pane.alpha",
166
- },
167
- });
168
- expect(
169
- reduceFixtureReceipt(current, {
170
- ...base,
171
- sequence: 3,
172
- phase: "observed",
173
- proof: {
174
- operationKind: "workspace.pane.send",
175
- observed: true,
176
- semanticPaneId: "pane.alpha",
177
- },
178
- }),
179
- ).toBe(current);
180
- });
181
-
182
- it("never derives activity copy from literal input", () => {
183
- const state = reduceFixtureReceipt(initialInteractionFeedState(), {
184
- ...base,
185
- sequence: 1,
186
- phase: "observed",
187
- proof: {
188
- operationKind: "workspace.pane.send",
189
- observed: true,
190
- semanticPaneId: "pane.alpha",
191
- },
192
- });
193
- expect(JSON.stringify(state)).not.toContain("prompt");
194
- expect(JSON.stringify(state)).toContain("84 characters");
195
- });
196
-
197
- it("projects metadata-only external observation without invented counts", () => {
198
- const state = reduceFixtureReceipt(initialInteractionFeedState(), {
199
- ...base,
200
- sequence: 1,
201
- origin: "external",
202
- phase: "observed",
203
- summary: { operationKind: "workspace.pane.send", observedOnly: true },
204
- proof: {
205
- operationKind: "workspace.pane.send",
206
- observed: true,
207
- semanticPaneId: "pane.alpha",
208
- },
209
- });
210
- expect(interactionForPane(state, endpoint("pane.alpha"))?.label).toBe(
211
- "external observed · input command observed",
212
- );
213
- expect(JSON.stringify(state)).not.toMatch(/characterCount|byteCount|submitted/u);
214
- });
215
-
216
- it("projects one authenticated pane relationship onto both endpoints", () => {
217
- const state = reduceFixtureReceipt(initialInteractionFeedState(), {
218
- ...base,
219
- sequence: 1,
220
- phase: "observed",
221
- sourceSemanticPaneId: "pane.editor",
222
- target: { kind: "pane", semanticPaneId: "pane.tests" },
223
- proof: {
224
- operationKind: "workspace.pane.send",
225
- observed: true,
226
- semanticPaneId: "pane.tests",
227
- },
228
- });
229
-
230
- expect(interactionForPane(state, endpoint("pane.editor"))).toMatchObject({
231
- direction: "outgoing",
232
- sourcePaneId: "pane.editor",
233
- destinationPaneId: "pane.tests",
234
- });
235
- expect(interactionForPane(state, endpoint("pane.tests"))).toMatchObject({
236
- direction: "incoming",
237
- sourcePaneId: "pane.editor",
238
- destinationPaneId: "pane.tests",
239
- });
240
- expect(
241
- paneInteractionRelationshipLabel(
242
- interactionForPane(state, endpoint("pane.tests"))!,
243
- (endpoint) =>
244
- ({ "pane.editor": "Editor", "pane.tests": "Tests" })[endpoint.semanticPaneId] ??
245
- endpoint.semanticPaneId,
246
- ),
247
- ).toBe("Editor → Tests");
248
- });
249
-
250
- it("labels raw tmux traffic as external without inventing a source", () => {
251
- expect(
252
- paneInteractionRelationshipLabel({
253
- origin: "external",
254
- sourceEndpoint: null,
255
- destinationEndpoint: endpoint("pane.tests"),
256
- }),
257
- ).toBe("External input → pane.tests");
258
- });
259
-
260
- it("projects pane reads without retaining captured terminal content", () => {
261
- const state = reduceFixtureReceipt(initialInteractionFeedState(), {
262
- ...base,
263
- sequence: 1,
264
- origin: "external",
265
- operationKind: "workspace.pane.read",
266
- phase: "observed",
267
- summary: { operationKind: "workspace.pane.read", observedOnly: true },
268
- proof: {
269
- operationKind: "workspace.pane.read",
270
- observed: true,
271
- semanticPaneId: "pane.tests",
272
- },
273
- target: { kind: "pane", semanticPaneId: "pane.tests" },
274
- });
275
- const interaction = interactionForPane(state, endpoint("pane.tests"))!;
276
- expect(interaction).toMatchObject({
277
- operationKind: "workspace.pane.read",
278
- direction: "incoming",
279
- sourcePaneId: null,
280
- });
281
- expect(paneInteractionRelationshipLabel(interaction, () => "Tests")).toBe(
282
- "External reader reads Tests",
283
- );
284
- expect(JSON.stringify(state)).not.toContain("content");
285
- });
286
-
287
- it("keeps observation, transfer, and focus as separate semantics", () => {
288
- const read = reduceFixtureReceipt(initialInteractionFeedState(), {
289
- ...base,
290
- sequence: 1,
291
- operationKind: "workspace.pane.read",
292
- phase: "observed",
293
- summary: { operationKind: "workspace.pane.read", observedOnly: true },
294
- proof: {
295
- operationKind: "workspace.pane.read",
296
- observed: true,
297
- semanticPaneId: "pane.alpha",
298
- },
299
- });
300
- expect(paneInteractionPresence(interactionForPane(read, endpoint("pane.alpha"))!)).toEqual({
301
- role: "read-target",
302
- kind: "read",
303
- endpoint: "target",
304
- treatment: "observation",
305
- tone: "info",
306
- badge: "READ",
307
- });
308
-
309
- const send = reduceFixtureReceipt(initialInteractionFeedState(), {
310
- ...base,
311
- sequence: 1,
312
- phase: "observed",
313
- sourceSemanticPaneId: "pane.editor",
314
- target: { kind: "pane", semanticPaneId: "pane.tests" },
315
- proof: {
316
- operationKind: "workspace.pane.send",
317
- observed: true,
318
- semanticPaneId: "pane.tests",
319
- },
320
- });
321
- expect(
322
- paneInteractionPresence(interactionForPane(send, endpoint("pane.editor"))!),
323
- ).toMatchObject({
324
- role: "send-source",
325
- treatment: "transfer",
326
- badge: "SENT",
327
- });
328
- expect(
329
- paneInteractionPresence(interactionForPane(send, endpoint("pane.tests"))!),
330
- ).toMatchObject({
331
- role: "send-target",
332
- badge: "RECEIVED",
333
- });
334
- expect(
335
- paneInteractionPresence(interactionForPane(send, endpoint("pane.tests"))!),
336
- ).not.toHaveProperty("focused");
337
- });
338
-
339
- it("keeps structural receipts in Activity without inventing pane communication", () => {
340
- const state = reduceFixtureReceipt(initialInteractionFeedState(), {
341
- ...base,
342
- sequence: 1,
343
- operationKind: "workspace.pane.resize",
344
- target: { kind: "pane", semanticPaneId: "pane.tests" },
345
- phase: "observed",
346
- summary: { operationKind: "workspace.pane.resize", axis: "cols", cells: 120 },
347
- proof: {
348
- operationKind: "workspace.pane.resize",
349
- outcome: "applied",
350
- semanticPaneId: "pane.tests",
351
- axis: "cols",
352
- cells: 118,
353
- },
354
- });
355
-
356
- expect(state.activity[0]).toMatchObject({
357
- operationKind: "workspace.pane.resize",
358
- target: { kind: "pane", semanticPaneId: "pane.tests" },
359
- });
360
- expect(onlyReceipt(state.activity[0]).summary).not.toHaveProperty("text");
361
- expect(state.panes).toEqual({});
362
- });
363
-
364
- it("uses request-neutral copy until a mutation is actually observed", () => {
365
- const closePane = {
366
- ...base,
367
- operationKind: "workspace.pane.kill" as const,
368
- summary: { operationKind: "workspace.pane.kill" as const },
369
- };
370
- expect(fixtureReceiptLabel({ ...closePane, sequence: 1, phase: "accepted" })).toBe(
371
- "sdk accepted · close pane",
372
- );
373
- expect(fixtureReceiptLabel({ ...closePane, sequence: 2, phase: "rejected" })).toBe(
374
- "sdk rejected · close pane",
375
- );
376
- expect(fixtureReceiptLabel({ ...closePane, sequence: 3, phase: "timed-out" })).toBe(
377
- "sdk timed out · close pane",
378
- );
379
- expect(
380
- fixtureReceiptLabel({
381
- ...closePane,
382
- sequence: 4,
383
- phase: "observed",
384
- proof: {
385
- operationKind: "workspace.pane.kill",
386
- outcome: "applied",
387
- semanticPaneId: "pane.alpha",
388
- windowClosed: false,
389
- remainingWindowCount: 2,
390
- },
391
- }),
392
- ).toBe("sdk observed · pane closed");
393
-
394
- expect(fixtureReceiptLabel({ ...base, sequence: 5, phase: "accepted" })).toContain(
395
- "send 84 characters",
396
- );
397
- expect(fixtureReceiptLabel({ ...base, sequence: 6, phase: "rejected" })).not.toMatch(
398
- /delivered|received/u,
399
- );
400
- });
401
-
402
- it("enforces immutable operation identity and one-way lifecycle transitions", () => {
403
- const accepted = reduceFixtureReceipt(initialInteractionFeedState(), {
404
- ...base,
405
- sequence: 1,
406
- phase: "accepted",
407
- });
408
- const withStaleProjection = {
409
- ...accepted,
410
- panes: Object.freeze({
411
- ...accepted.panes,
412
- "pane.stale": {
413
- ...accepted.panes[interactionPaneEndpointKey(endpoint("pane.alpha"))]!,
414
- paneId: "pane.stale",
415
- },
416
- }),
417
- };
418
- const observed = reduceFixtureReceipt(withStaleProjection, {
419
- ...base,
420
- sequence: 2,
421
- phase: "observed",
422
- sourceSemanticPaneId: "pane.editor",
423
- proof: {
424
- operationKind: "workspace.pane.send",
425
- observed: true,
426
- semanticPaneId: "pane.alpha",
427
- },
428
- });
429
- expect(onlyReceipt(observed.activity[0]).phase).toBe("observed");
430
- expect(observed.panes).not.toHaveProperty("pane.stale");
431
- expect(interactionForPane(observed, endpoint("pane.editor"))).not.toBeNull();
432
-
433
- const regressed = reduceFixtureReceipt(observed, {
434
- ...base,
435
- sequence: 3,
436
- phase: "accepted",
437
- });
438
- expect(regressed.sequence).toBe(3);
439
- expect(onlyReceipt(regressed.activity[0]).phase).toBe("observed");
440
- expect(regressed.panes[interactionPaneEndpointKey(endpoint("pane.alpha"))]?.sequence).toBe(2);
441
-
442
- const mutated = reduceFixtureReceipt(regressed, {
443
- ...base,
444
- sequence: 4,
445
- phase: "observed",
446
- target: { kind: "pane", semanticPaneId: "pane.other" },
447
- proof: {
448
- operationKind: "workspace.pane.send",
449
- observed: true,
450
- semanticPaneId: "pane.other",
451
- },
452
- });
453
- expect(mutated.sequence).toBe(4);
454
- expect(onlyReceipt(mutated.activity[0]).target).toEqual({
455
- kind: "pane",
456
- semanticPaneId: "pane.alpha",
457
- });
458
- expect(mutated.panes).not.toHaveProperty("pane.other");
459
- });
460
- });
461
-
462
- describe("scoped receipt evidence", () => {
463
- it("keeps colliding server cursors, operation IDs and semantic IDs independent", () => {
464
- const a = fixtureReceipt({ ...base, sequence: 10, phase: "accepted" });
465
- const b = structuredClone(a);
466
- b.sequence = 1;
467
- b.evidence!.endpoints.destination.serverScope.serverId = `tmux-server.${"b".repeat(32)}`;
468
- const state = reduceReceipt(reduceReceipt(initialInteractionFeedState(), a), b);
469
- expect(state.activity).toHaveLength(2);
470
- expect(Object.keys(state.panes)).toHaveLength(2);
471
- expect(interactionForPane(state, endpoint("pane.alpha"))?.sequence).toBe(10);
472
- expect(
473
- interactionForPane(state, {
474
- ...endpoint("pane.alpha"),
475
- paneLifetimeId: "00000000-0000-4000-8000-000000000009",
476
- }),
477
- ).toBeNull();
478
- });
479
- it("keeps stock observation neutral and rejects same-phase evidence downgrade", () => {
480
- const raw = {
481
- ...base,
482
- origin: "external",
483
- sequence: 1,
484
- phase: "observed",
485
- summary: { operationKind: "workspace.pane.send", observedOnly: true },
486
- proof: { operationKind: "workspace.pane.send", observed: true, semanticPaneId: "pane.alpha" },
487
- };
488
- const stock = fixtureReceipt(raw);
489
- const state = reduceReceipt(initialInteractionFeedState(), stock);
490
- expect(
491
- paneInteractionPresence(interactionForPane(state, endpoint("pane.alpha"))!),
492
- ).toMatchObject({ badge: "INPUT OBSERVED" });
493
- const forged = structuredClone(stock);
494
- forged.sequence = 2;
495
- forged.evidence!.revision = 2;
496
- forged.evidence!.endpoints.destination = {
497
- ...endpoint("pane.alpha"),
498
- paneLifetimeId: "00000000-0000-4000-8000-000000000009",
499
- };
500
- expect(reduceReceipt(state, forged).activity).toEqual(state.activity);
501
- });
502
- });
503
-
504
- describe("native evidence journal projection", () => {
505
- function native(sequence = 1) {
506
- return InteractionEvidenceRecordSchemaZ.parse({
507
- type: "interaction.evidence",
508
- sequence,
509
- evidence: {
510
- schemaVersion: 1,
511
- interactionId: fixtureId,
512
- revision: 0,
513
- endpoints: { destination: endpoint("pane.native"), source: null },
514
- actor: { kind: "unknown", reason: "unavailable" },
515
- observation: {
516
- kind: "native-journal",
517
- serverEpoch: fixtureId,
518
- command: "unknown",
519
- cursor: { epoch: fixtureId, sequence: String(sequence) },
520
- commandId: null,
521
- parentCommandId: null,
522
- correlatedOperationId: null,
523
- },
524
- effect: { kind: "input-enqueued" },
525
- occurredAt: null,
526
- timeBasis: "unknown",
527
- receivedAt: "2026-09-28T00:00:00.000Z",
528
- },
529
- });
530
- }
531
- it("preserves unresolved effects without fabricating semantic fields", () => {
532
- const entry = native();
533
- entry.evidence.endpoints.destination = {
534
- kind: "unresolved-pane",
535
- environmentId: fixtureId,
536
- serverScope: endpoint("x").serverScope,
537
- observationRef: fixtureId,
538
- };
539
- const state = reduceReceipt(initialInteractionFeedState(), entry);
540
- expect(state.activity).toEqual([entry]);
541
- expect(state.panes).toEqual({});
542
- expect(interactionReceiptLabel(entry)).toBe("External input enqueued");
543
- expect(state.activity[0]).not.toHaveProperty("workspaceName");
544
- });
545
- it("retains proven viewer evidence without turning it into pane activity", () => {
546
- const entry = native();
547
- entry.evidence.actor = {
548
- kind: "native",
549
- issuerId: fixtureId,
550
- identity: "connection",
551
- sourceBindingId: null,
552
- classification: { kind: "viewer", bindingId: fixtureId },
553
- };
554
- const state = reduceReceipt(initialInteractionFeedState(), entry);
555
- expect(state.activity).toEqual([entry]);
556
- expect(state.sequence).toBe(1);
557
- expect(interactionForPane(state, endpoint("pane.native"))).toBeNull();
558
-
559
- const physical = native(2);
560
- physical.evidence.actor = entry.evidence.actor;
561
- physical.evidence.endpoints.destination = {
562
- kind: "native-pane",
563
- environmentId: fixtureId,
564
- serverScope: endpoint("x").serverScope,
565
- serverEpoch: fixtureId,
566
- paneBirthId: "7",
567
- };
568
- const current = reduceReceipt(initialInteractionFeedState(), physical);
569
- expect(current.activity).toEqual([physical]);
570
- expect(
571
- interactionForPane(current, endpoint("pane.native"), {
572
- serverEpoch: fixtureId,
573
- paneBirthId: "7",
574
- }),
575
- ).toBeNull();
576
- physical.evidence.actor = { kind: "unknown", reason: "unavailable" };
577
- const unknown = reduceReceipt(initialInteractionFeedState(), physical);
578
- expect(
579
- interactionForPane(unknown, endpoint("pane.native"), {
580
- serverEpoch: fixtureId,
581
- paneBirthId: "7",
582
- })?.effect.kind,
583
- ).toBe("input-enqueued");
584
- });
585
- it("projects only resolved full lifetime and rejects downgraded replay enrichment", () => {
586
- const entry = native();
587
- const state = reduceReceipt(initialInteractionFeedState(), entry);
588
- expect(interactionForPane(state, endpoint("pane.native"))?.effect.kind).toBe("input-enqueued");
589
- const downgrade = native(2);
590
- downgrade.evidence.revision = 1;
591
- downgrade.evidence.effect = { kind: "unknown" };
592
- const next = reduceReceipt(state, downgrade);
593
- expect(next.activity).toEqual([entry]);
594
- expect(next.sequence).toBe(2);
595
- expect(
596
- interactionForPane(next, {
597
- ...endpoint("pane.native"),
598
- paneLifetimeId: "22222222-2222-4222-8222-222222222222",
599
- }),
600
- ).toBeNull();
601
- });
602
- it("retains unknown commands without inventing send presence", () => {
603
- const entry = native();
604
- entry.evidence.effect = { kind: "unknown" };
605
- const state = reduceReceipt(initialInteractionFeedState(), entry);
606
- expect(state.activity).toHaveLength(1);
607
- expect(state.panes).toEqual({});
608
- });
609
- });
610
-
611
- it("projects physical history through current linked aliases without rewriting provenance", () => {
612
- const nativeIdentity = { serverEpoch: fixtureId, paneBirthId: "7" };
613
- const physical = {
614
- kind: "native-pane" as const,
615
- environmentId: fixtureId,
616
- serverScope: endpoint("a").serverScope,
617
- ...nativeIdentity,
618
- };
619
- const entry = InteractionEvidenceRecordSchemaZ.parse({
620
- type: "interaction.evidence",
621
- sequence: 1,
622
- evidence: {
623
- schemaVersion: 1,
624
- interactionId: fixtureId,
625
- revision: 0,
626
- endpoints: { destination: physical, source: null },
627
- actor: { kind: "unknown", reason: "unavailable" },
628
- observation: {
629
- kind: "native-journal",
630
- serverEpoch: fixtureId,
631
- command: "send-keys",
632
- cursor: { epoch: "22222222-2222-4222-8222-222222222222", sequence: "1" },
633
- commandId: null,
634
- parentCommandId: null,
635
- correlatedOperationId: null,
636
- },
637
- effect: { kind: "input-enqueued" },
638
- occurredAt: null,
639
- timeBasis: "unknown",
640
- receivedAt: "2026-09-28T00:00:00.000Z",
641
- },
642
- });
643
- const state = reduceReceipt(initialInteractionFeedState(), entry);
644
- const aliasA = endpoint("pane.a");
645
- const aliasB = { ...endpoint("pane.b"), workspaceName: "linked" };
646
- expect(interactionForPane(state, aliasA)).toBeNull();
647
- for (const alias of [aliasA, aliasB]) {
648
- const projection = interactionForPane(state, alias, nativeIdentity)!;
649
- expect(projection.destinationEndpoint).toEqual(physical);
650
- expect(projection.displayDestinationEndpoint).toEqual(alias);
651
- expect(
652
- paneInteractionRelationshipLabel(projection, (e) => e.workspaceName + ":" + e.semanticPaneId),
653
- ).toBe("External input → " + alias.workspaceName + ":" + alias.semanticPaneId);
654
- }
655
- expect(interactionForPane(state, aliasA, { ...nativeIdentity, paneBirthId: "8" })).toBeNull();
656
- expect(
657
- interactionForPane(
658
- state,
659
- { ...aliasA, environmentId: "33333333-3333-4333-8333-333333333333" },
660
- nativeIdentity,
661
- ),
662
- ).toBeNull();
663
- expect(
664
- interactionForPane(state, aliasA, {
665
- ...nativeIdentity,
666
- serverEpoch: "33333333-3333-4333-8333-333333333333",
667
- }),
668
- ).toBeNull();
669
- expect(state.activity[0]).toEqual(entry);
670
- expect(state.panes).toEqual({});
671
- });
@@ -1,34 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { navigatorEntryMatches, parseNavigatorQuery } from "./navigator.ts";
3
-
4
- describe("parseNavigatorQuery", () => {
5
- it("extracts renderer-neutral scope and status tokens", () => {
6
- expect(parseNavigatorQuery("deploy @agents #blocked api")).toEqual({
7
- scope: "agents",
8
- status: "blocked",
9
- query: "deploy api",
10
- });
11
- });
12
-
13
- it("accepts singular aliases and leaves ordinary text intact", () => {
14
- expect(parseNavigatorQuery("@pane editor")).toEqual({
15
- scope: "panes",
16
- status: null,
17
- query: "editor",
18
- });
19
- expect(parseNavigatorQuery("claude code")).toEqual({
20
- scope: "all",
21
- status: null,
22
- query: "claude code",
23
- });
24
- });
25
- });
26
-
27
- describe("navigatorEntryMatches", () => {
28
- it("applies the same scope and status law to every renderer", () => {
29
- const blockedAgent = { scope: "agents" as const, status: "blocked" as const };
30
- expect(navigatorEntryMatches(blockedAgent, { scope: "agents", status: "blocked" })).toBe(true);
31
- expect(navigatorEntryMatches(blockedAgent, { scope: "panes", status: "blocked" })).toBe(false);
32
- expect(navigatorEntryMatches(blockedAgent, { scope: "all", status: "working" })).toBe(false);
33
- });
34
- });