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.
Files changed (267) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +121 -140
  3. package/bin/cli.js +2457 -727
  4. package/package.json +23 -8
  5. package/packages/contracts/src/desktop-host.ts +3 -0
  6. package/packages/contracts/src/saved-machines.ts +19 -0
  7. package/packages/contracts/src/terminal-replica.ts +1 -1
  8. package/packages/core/package.json +3 -2
  9. package/packages/core/src/terminal-delivery.ts +51 -3
  10. package/packages/core/src/terminal-fnv64-wasm.ts +4 -3
  11. package/packages/core/src/terminal-replica-hash-cache.ts +129 -31
  12. package/packages/core/src/terminal-replica-owned-row.ts +27 -0
  13. package/packages/core/src/terminal-replica.ts +13 -28
  14. package/packages/daemon/dist/command-center/daemon-fleet-facts-observer.js +96 -10
  15. package/packages/daemon/dist/command-center/resources/saved-machine-route.js +40 -1
  16. package/packages/daemon/dist/command-center/ws-events.js +5 -24
  17. package/packages/daemon/dist/lib/canonical-daemon-bootstrap.js +8 -0
  18. package/packages/daemon/dist/lib/canonical-daemon.js +28 -2
  19. package/packages/daemon/dist/lib/daemon-embed.js +1 -1
  20. package/packages/daemon/dist/lib/daemon-service-manager.js +122 -0
  21. package/packages/daemon/dist/lib/daemon-service-plan.js +127 -0
  22. package/packages/daemon/dist/lib/daemon-service.js +259 -0
  23. package/packages/daemon/dist/lib/install-origin.js +2 -0
  24. package/packages/daemon/dist/lib/local-fleet-request.js +9 -3
  25. package/packages/daemon/dist/lib/log.js +6 -10
  26. package/packages/daemon/dist/lib/managed-installer-update.js +67 -0
  27. package/packages/daemon/dist/lib/{tui-download-lock.js → private-operation-lock.js} +11 -11
  28. package/packages/daemon/dist/lib/remote-daemon-info.js +3 -2
  29. package/packages/daemon/dist/lib/remote-daemon-lifecycle.js +4 -4
  30. package/packages/daemon/dist/lib/remote-tmux-command.js +10 -0
  31. package/packages/daemon/dist/lib/runtime-namespace.js +28 -16
  32. package/packages/daemon/dist/lib/saved-machines.js +40 -2
  33. package/packages/daemon/dist/lib/ssh-daemon-transport.js +24 -9
  34. package/packages/daemon/dist/lib/tmux-server-owner.js +1 -1
  35. package/packages/daemon/dist/lib/tmux-server-registration.js +21 -3
  36. package/packages/daemon/dist/lib/tui-binary.js +2 -2
  37. package/packages/daemon/dist/lib/update.js +18 -0
  38. package/packages/daemon/dist/lib/workspace-multiplexer-verbs.js +24 -1
  39. package/packages/daemon/dist/machines.js +40 -4
  40. package/packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/Info.plist +2 -2
  41. package/packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/MacOS/tmux-ide-notifier +0 -0
  42. package/packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/Resources/Assets.car +0 -0
  43. package/packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/_CodeSignature/CodeResources +2 -2
  44. package/packages/daemon/dist/terminal/attachments/direct-websocket.js +4 -1
  45. package/packages/daemon/dist/terminal/attachments/native-runtime.js +22 -13
  46. package/packages/daemon/dist/terminal/mirror/mirror-service.js +101 -3
  47. package/packages/daemon/dist/terminal/mirror/registered-window-guard.js +62 -0
  48. package/packages/daemon/dist/terminal/mirror/session-channel.js +75 -4
  49. package/packages/daemon/dist/terminal/mirror/shared-window-index.js +45 -0
  50. package/packages/daemon/dist/terminal/pane-stream/pane-stream-websocket.js +11 -1
  51. package/packages/daemon/dist/terminal/session-runtime/multiplexer-backend.js +1 -0
  52. package/packages/daemon/dist/terminal/session-runtime/registry.js +56 -7
  53. package/packages/daemon/dist/terminal/session-runtime/semantic-mutation-executor.js +3 -1
  54. package/packages/daemon/dist/tui/integrations/claude-agent-teams.js +264 -0
  55. package/packages/daemon/dist/tui/mirror/dialog-model.js +2 -35
  56. package/packages/daemon/dist/tui/mirror/runtime/application-daemon-authority-owner.js +8 -0
  57. package/packages/daemon/dist/tui/mirror/runtime/application-home-fleet.js +20 -2
  58. package/packages/daemon/dist/tui/mirror/runtime/application-machine-agents.js +7 -1
  59. package/packages/daemon/dist/tui/mirror/runtime/application-machine-authority.js +59 -9
  60. package/packages/daemon/dist/tui/mirror/runtime/application-machine-navigation.js +27 -19
  61. package/packages/daemon/dist/tui/mirror/runtime/application-machine-sidebar.jsx +23 -18
  62. package/packages/daemon/dist/tui/mirror/runtime/application-machine-startup.js +31 -2
  63. package/packages/daemon/dist/tui/mirror/runtime/application-palette-search-owner.js +7 -3
  64. package/packages/daemon/dist/tui/mirror/runtime/application-performance-log.js +3 -0
  65. package/packages/daemon/dist/tui/mirror/runtime/application-terminal-input-ingress.js +146 -2
  66. package/packages/daemon/dist/tui/mirror/runtime/application-terminal-interaction-controller.js +201 -50
  67. package/packages/daemon/dist/tui/mirror/runtime/bounded-performance-record-writer.js +50 -10
  68. package/packages/daemon/dist/tui/mirror/runtime/terminal-fast-lane-renderer-adapter.js +6 -5
  69. package/packages/daemon/dist/tui/mirror/runtime/terminal-pane-input-router.js +3 -0
  70. package/packages/daemon/dist/tui/mirror/runtime/workspace-terminal-fast-lane.js +8 -2
  71. package/packages/daemon/dist/tui/mirror/terminal-text.js +35 -0
  72. package/packages/daemon/dist/tui/mirror/workspace/connection-feedback.js +5 -3
  73. package/packages/daemon/src/command-center/daemon-fleet-facts-observer.ts +100 -10
  74. package/packages/daemon/src/command-center/resources/saved-machine-route.ts +48 -1
  75. package/packages/daemon/src/command-center/ws-events.ts +5 -25
  76. package/packages/daemon/src/lib/canonical-daemon-bootstrap.ts +12 -0
  77. package/packages/daemon/src/lib/canonical-daemon.ts +44 -2
  78. package/packages/daemon/src/lib/daemon-embed.ts +1 -0
  79. package/packages/daemon/src/lib/daemon-service-manager.ts +152 -0
  80. package/packages/daemon/src/lib/daemon-service-plan.ts +153 -0
  81. package/packages/daemon/src/lib/daemon-service.ts +301 -0
  82. package/packages/daemon/src/lib/install-origin.ts +5 -0
  83. package/packages/daemon/src/lib/local-fleet-request.ts +19 -3
  84. package/packages/daemon/src/lib/log.ts +13 -9
  85. package/packages/daemon/src/lib/managed-installer-update.ts +79 -0
  86. package/packages/daemon/src/lib/{tui-download-lock.ts → private-operation-lock.ts} +15 -11
  87. package/packages/daemon/src/lib/remote-daemon-info.ts +3 -3
  88. package/packages/daemon/src/lib/remote-daemon-lifecycle.ts +4 -4
  89. package/packages/daemon/src/lib/remote-tmux-command.ts +12 -0
  90. package/packages/daemon/src/lib/runtime-namespace.ts +27 -18
  91. package/packages/daemon/src/lib/saved-machines.ts +40 -1
  92. package/packages/daemon/src/lib/ssh-daemon-transport.ts +25 -7
  93. package/packages/daemon/src/lib/tmux-server-owner.ts +1 -0
  94. package/packages/daemon/src/lib/tmux-server-registration.ts +21 -3
  95. package/packages/daemon/src/lib/tui-binary.ts +2 -2
  96. package/packages/daemon/src/lib/update.ts +24 -0
  97. package/packages/daemon/src/lib/workspace-multiplexer-verbs.ts +22 -0
  98. package/packages/daemon/src/machines.ts +53 -5
  99. package/packages/daemon/src/terminal/attachments/direct-websocket.ts +8 -2
  100. package/packages/daemon/src/terminal/attachments/native-runtime.ts +28 -13
  101. package/packages/daemon/src/terminal/mirror/mirror-service.ts +105 -3
  102. package/packages/daemon/src/terminal/mirror/registered-window-guard.ts +66 -0
  103. package/packages/daemon/src/terminal/mirror/session-channel.ts +92 -4
  104. package/packages/daemon/src/terminal/mirror/shared-window-index.ts +42 -0
  105. package/packages/daemon/src/terminal/pane-stream/pane-stream-websocket.ts +12 -1
  106. package/packages/daemon/src/terminal/session-runtime/multiplexer-backend.ts +2 -0
  107. package/packages/daemon/src/terminal/session-runtime/registry.ts +70 -8
  108. package/packages/daemon/src/terminal/session-runtime/semantic-mutation-executor.ts +3 -1
  109. package/packages/daemon/src/tui/integrations/claude-agent-teams.ts +334 -0
  110. package/packages/daemon/src/tui/mirror/dialog-model.ts +2 -32
  111. package/packages/daemon/src/tui/mirror/runtime/application-daemon-authority-owner.ts +8 -0
  112. package/packages/daemon/src/tui/mirror/runtime/application-home-fleet.ts +19 -2
  113. package/packages/daemon/src/tui/mirror/runtime/application-machine-agents.ts +6 -1
  114. package/packages/daemon/src/tui/mirror/runtime/application-machine-authority.ts +60 -11
  115. package/packages/daemon/src/tui/mirror/runtime/application-machine-navigation.ts +39 -33
  116. package/packages/daemon/src/tui/mirror/runtime/application-machine-sidebar.tsx +31 -23
  117. package/packages/daemon/src/tui/mirror/runtime/application-machine-startup.ts +38 -2
  118. package/packages/daemon/src/tui/mirror/runtime/application-palette-search-owner.ts +7 -4
  119. package/packages/daemon/src/tui/mirror/runtime/application-performance-log.ts +3 -0
  120. package/packages/daemon/src/tui/mirror/runtime/application-root-v2.tsx +1 -1
  121. package/packages/daemon/src/tui/mirror/runtime/application-shell-view.tsx +47 -46
  122. package/packages/daemon/src/tui/mirror/runtime/application-terminal-input-ingress.ts +165 -2
  123. package/packages/daemon/src/tui/mirror/runtime/application-terminal-interaction-controller.ts +207 -53
  124. package/packages/daemon/src/tui/mirror/runtime/bounded-performance-record-writer.ts +49 -9
  125. package/packages/daemon/src/tui/mirror/runtime/terminal-fast-lane-renderer-adapter.ts +6 -5
  126. package/packages/daemon/src/tui/mirror/runtime/terminal-pane-input-router.ts +4 -0
  127. package/packages/daemon/src/tui/mirror/runtime/workspace-terminal-fast-lane.ts +8 -3
  128. package/packages/daemon/src/tui/mirror/terminal-text.ts +32 -0
  129. package/packages/daemon/src/tui/mirror/workspace/connection-feedback.ts +6 -3
  130. package/packages/daemon-client/src/fleet-connection-status.ts +10 -1
  131. package/packages/daemon-client/src/workspace-client.ts +4 -1
  132. package/skill/SKILL.md +30 -30
  133. package/packages/contracts/src/__tests__/actions-contract.test.ts +0 -119
  134. package/packages/contracts/src/__tests__/agent-graph-overlay.test.ts +0 -428
  135. package/packages/contracts/src/__tests__/app-window-mutation.test.ts +0 -51
  136. package/packages/contracts/src/__tests__/app-window-state.test.ts +0 -34
  137. package/packages/contracts/src/__tests__/application-shell.test.ts +0 -645
  138. package/packages/contracts/src/__tests__/automation-operations.test.ts +0 -78
  139. package/packages/contracts/src/__tests__/causal-cell.test.ts +0 -47
  140. package/packages/contracts/src/__tests__/client-view-state.test.ts +0 -115
  141. package/packages/contracts/src/__tests__/cohesion-fixture.test.ts +0 -106
  142. package/packages/contracts/src/__tests__/commands.test.ts +0 -86
  143. package/packages/contracts/src/__tests__/control.test.ts +0 -154
  144. package/packages/contracts/src/__tests__/daemon-events.test.ts +0 -405
  145. package/packages/contracts/src/__tests__/daemon-resources.test.ts +0 -143
  146. package/packages/contracts/src/__tests__/daemon-wire.test.ts +0 -149
  147. package/packages/contracts/src/__tests__/desktop-host.test.ts +0 -269
  148. package/packages/contracts/src/__tests__/desktop-missions.test.ts +0 -215
  149. package/packages/contracts/src/__tests__/experience-conformance.test.ts +0 -153
  150. package/packages/contracts/src/__tests__/experience-kernel-boundary.test.ts +0 -113
  151. package/packages/contracts/src/__tests__/experience-shell.test.ts +0 -65
  152. package/packages/contracts/src/__tests__/fixtures/daemon-wire-v2.json +0 -35
  153. package/packages/contracts/src/__tests__/fixtures/daemon-wire-v3.json +0 -35
  154. package/packages/contracts/src/__tests__/fixtures/daemon-wire-v4.json +0 -35
  155. package/packages/contracts/src/__tests__/fixtures/scoped-receipt.ts +0 -62
  156. package/packages/contracts/src/__tests__/fleet-agent-graph.test.ts +0 -231
  157. package/packages/contracts/src/__tests__/fleet-catalog.test.ts +0 -270
  158. package/packages/contracts/src/__tests__/fleet-lifecycle.test.ts +0 -62
  159. package/packages/contracts/src/__tests__/focus-overlay.test.ts +0 -110
  160. package/packages/contracts/src/__tests__/ide-config.test.ts +0 -64
  161. package/packages/contracts/src/__tests__/interaction-evidence.test.ts +0 -288
  162. package/packages/contracts/src/__tests__/interaction-receipt-v2.test.ts +0 -72
  163. package/packages/contracts/src/__tests__/issue-error.test.ts +0 -78
  164. package/packages/contracts/src/__tests__/mission-projections.test.ts +0 -186
  165. package/packages/contracts/src/__tests__/missions.test.ts +0 -272
  166. package/packages/contracts/src/__tests__/multiplexer-verbs.test.ts +0 -242
  167. package/packages/contracts/src/__tests__/pane-appearance.test.ts +0 -146
  168. package/packages/contracts/src/__tests__/pane-read-result.test.ts +0 -55
  169. package/packages/contracts/src/__tests__/pane-stream.test.ts +0 -536
  170. package/packages/contracts/src/__tests__/pane-widget-marker.test.ts +0 -327
  171. package/packages/contracts/src/__tests__/performance-metrics.test.ts +0 -73
  172. package/packages/contracts/src/__tests__/performance-qualification.test.ts +0 -137
  173. package/packages/contracts/src/__tests__/rich-card-widget.test.ts +0 -29
  174. package/packages/contracts/src/__tests__/session-runtime.test.ts +0 -512
  175. package/packages/contracts/src/__tests__/startup-readiness.test.ts +0 -409
  176. package/packages/contracts/src/__tests__/terminal-attachment-stream.test.ts +0 -72
  177. package/packages/contracts/src/__tests__/terminal-attachments.test.ts +0 -329
  178. package/packages/contracts/src/__tests__/terminal-delivery.test.ts +0 -88
  179. package/packages/contracts/src/__tests__/terminal-runtime-inventory.test.ts +0 -68
  180. package/packages/contracts/src/__tests__/terminals.test.ts +0 -87
  181. package/packages/contracts/src/__tests__/tmux-server-scope.test.ts +0 -166
  182. package/packages/contracts/src/__tests__/transport-contract-loading.test.ts +0 -91
  183. package/packages/contracts/src/__tests__/visual-tokens.test.ts +0 -224
  184. package/packages/contracts/src/__tests__/window-links.test.ts +0 -243
  185. package/packages/contracts/src/__tests__/workspace-changes-resource.test.ts +0 -317
  186. package/packages/contracts/src/__tests__/workspace-changes-view.test.ts +0 -122
  187. package/packages/contracts/src/__tests__/workspace-config.test.ts +0 -294
  188. package/packages/contracts/src/__tests__/workspace-files-resource.test.ts +0 -261
  189. package/packages/contracts/src/__tests__/workspace-files-tree.test.ts +0 -147
  190. package/packages/contracts/src/__tests__/workspace-pane-creation.test.ts +0 -249
  191. package/packages/contracts/src/__tests__/workspace-promotion.test.ts +0 -94
  192. package/packages/contracts/src/__tests__/workspace-resource-identity.test.ts +0 -90
  193. package/packages/contracts/src/daemon-resource-request.test.ts +0 -192
  194. package/packages/contracts/src/native-operation-identity.test.ts +0 -23
  195. package/packages/contracts/src/workspace-admission.test.ts +0 -21
  196. package/packages/contracts/src/workspace-catalog-resource.test.ts +0 -146
  197. package/packages/core/src/agent-provisioning.test.ts +0 -42
  198. package/packages/core/src/application-shell-session.test.ts +0 -105
  199. package/packages/core/src/interaction-evidence.test.ts +0 -134
  200. package/packages/core/src/interaction-flow.test.ts +0 -66
  201. package/packages/core/src/interaction-receipts.test.ts +0 -671
  202. package/packages/core/src/navigator.test.ts +0 -34
  203. package/packages/core/src/optimistic-projection-conformance.test.ts +0 -75
  204. package/packages/core/src/optimistic-projection.test.ts +0 -118
  205. package/packages/core/src/performance-metrics.test.ts +0 -121
  206. package/packages/core/src/performance-qualification.test.ts +0 -283
  207. package/packages/core/src/saved-machines.test.ts +0 -80
  208. package/packages/core/src/terminal-compact-cold.test.ts +0 -87
  209. package/packages/core/src/terminal-conformance.test.ts +0 -48
  210. package/packages/core/src/terminal-delivery-cache-lifetime.test.ts +0 -167
  211. package/packages/core/src/terminal-delivery-encode-cooperative.test.ts +0 -140
  212. package/packages/core/src/terminal-delivery-representation-hash.test.ts +0 -77
  213. package/packages/core/src/terminal-delivery.test.ts +0 -1471
  214. package/packages/core/src/terminal-fnv64-wasm.test.ts +0 -61
  215. package/packages/core/src/terminal-replica-cold.test.ts +0 -31
  216. package/packages/core/src/terminal-replica-cooperative.test.ts +0 -170
  217. package/packages/core/src/terminal-replica-hash-cache.test.ts +0 -283
  218. package/packages/core/src/terminal-replica.test.ts +0 -347
  219. package/packages/core/src/workspace-selection.test.ts +0 -63
  220. package/packages/daemon/dist/__tests__/support.js +0 -33
  221. package/packages/daemon/dist/lib/__tests__/fixtures/workspace-state-writer.js +0 -58
  222. package/packages/daemon/dist/lib/__tests__/installed-recovery-fixture.js +0 -400
  223. package/packages/daemon/dist/terminal/__tests__/MockPtyAdapter.js +0 -182
  224. package/packages/daemon/dist/terminal/mirror/__tests__/scripted-channel.js +0 -98
  225. package/packages/daemon/dist/terminal/mirror/__tests__/simulated-channel.js +0 -156
  226. package/packages/daemon/src/tui/mirror/__snapshots__/activity-surface-renderer.test.tsx.snap +0 -42
  227. package/packages/daemon/src/tui/mirror/__snapshots__/changes-terminal-surface-renderer.test.tsx.snap +0 -267
  228. package/packages/daemon/src/tui/mirror/__snapshots__/home-files-surface-renderer.test.tsx.snap +0 -267
  229. package/packages/daemon/src/tui/mirror/__snapshots__/missions-surface-renderer.test.tsx.snap +0 -134
  230. package/packages/daemon/src/tui/mirror/__snapshots__/recipes-gallery-renderer.test.tsx.snap +0 -141
  231. package/packages/daemon/src/tui/mirror/__snapshots__/shell-chrome-renderer.test.tsx.snap +0 -134
  232. package/packages/daemon/src/tui/mirror/runtime/__snapshots__/application-shell-view-renderer.test.tsx.snap +0 -87
  233. package/packages/daemon/src/tui/mirror/workspace/__snapshots__/agent-terminal-canvas-renderer.test.tsx.snap +0 -348
  234. package/packages/daemon/src/tui/mirror/workspace/__snapshots__/application-shell-renderer.test.tsx.snap +0 -134
  235. package/packages/daemon/src/tui/mirror/workspace/__snapshots__/command-palette-surface-renderer.test.tsx.snap +0 -255
  236. package/packages/daemon/src/tui/mirror/workspace/__snapshots__/pane-frame-renderer.test.tsx.snap +0 -525
  237. package/packages/daemon/src/tui/mirror/workspace/__snapshots__/terminal-pane-header-polish-renderer.test.tsx.snap +0 -31
  238. package/packages/daemon/src/tui/mirror/workspace/__snapshots__/workbench-shell-renderer.test.tsx.snap +0 -134
  239. package/packages/daemon-client/src/application-shell-session.test.ts +0 -196
  240. package/packages/daemon-client/src/automation-client.test.ts +0 -214
  241. package/packages/daemon-client/src/bootstrap-coordinator.test.ts +0 -145
  242. package/packages/daemon-client/src/connection-supervisor.test.ts +0 -109
  243. package/packages/daemon-client/src/direct-application-shell-transport.test.ts +0 -941
  244. package/packages/daemon-client/src/first-latest-coordinator.test.ts +0 -175
  245. package/packages/daemon-client/src/fleet-dial-scheduler.test.ts +0 -114
  246. package/packages/daemon-client/src/fleet-environments.test.ts +0 -40
  247. package/packages/daemon-client/src/generation-bound-store-timers.test.ts +0 -74
  248. package/packages/daemon-client/src/owner-action-client.test.ts +0 -245
  249. package/packages/daemon-client/src/pane-stream-client.test.ts +0 -2841
  250. package/packages/daemon-client/src/pane-stream-clock-calibration.test.ts +0 -207
  251. package/packages/daemon-client/src/pane-stream-loopback-benchmark.test.ts +0 -51
  252. package/packages/daemon-client/src/push-resource-session.test.ts +0 -509
  253. package/packages/daemon-client/src/resource-replica.test.ts +0 -186
  254. package/packages/daemon-client/src/runtime-resource-ledger.test.ts +0 -18
  255. package/packages/daemon-client/src/scoped-tmux-server-transport.test.ts +0 -114
  256. package/packages/daemon-client/src/terminal-fast-lane.test.ts +0 -835
  257. package/packages/daemon-client/src/tmux-server-client.test.ts +0 -279
  258. package/packages/daemon-client/src/tmux-server-interaction-events.test.ts +0 -230
  259. package/packages/daemon-client/src/workspace-catalog-v2.test.ts +0 -109
  260. package/packages/daemon-client/src/workspace-client-boundaries.test.ts +0 -59
  261. package/packages/daemon-client/src/workspace-client-operations.test.ts +0 -96
  262. package/packages/daemon-client/src/workspace-client.test.ts +0 -2912
  263. package/packages/daemon-client/src/workspace-event-supervisor.test.ts +0 -1086
  264. package/packages/daemon-client/src/workspace-pane-client.test.ts +0 -80
  265. package/packages/presentation/src/presentation-contract.test.ts +0 -63
  266. package/packages/tmux-bridge/src/runner.test.ts +0 -614
  267. package/packages/tmux-bridge/src/targeting.test.ts +0 -107
@@ -1,329 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import {
3
- TERMINAL_ATTACHMENT_MAX_COLS,
4
- TERMINAL_ATTACHMENT_MAX_ROWS,
5
- TERMINAL_ATTACHMENT_MIN_COLS,
6
- TERMINAL_ATTACHMENT_MIN_ROWS,
7
- TERMINAL_ATTACHMENT_ISSUE_PATH,
8
- TERMINAL_ATTACHMENT_PROTOCOL_VERSION,
9
- TERMINAL_ATTACHMENT_REDEEM_PATH,
10
- TERMINAL_ATTACHMENT_WEBSOCKET_SUBPROTOCOL,
11
- TerminalAttachRequestSchemaZ,
12
- TerminalAttachmentErrorSchemaZ,
13
- TerminalAttachmentIssueDescriptorSchemaZ,
14
- TerminalAttachmentIssueErrorSchemaZ,
15
- TerminalAttachmentIssueMutationRequestSchemaZ,
16
- TerminalAttachmentIssueResultSchemaZ,
17
- TerminalAttachmentPlanResponseSchemaZ,
18
- TerminalAttachmentSemanticPaneIdSchemaZ,
19
- TerminalAttachmentSemanticWindowIdSchemaZ,
20
- } from "../terminal-attachments.ts";
21
- import { WORKSPACE_SEMANTIC_WINDOW_OPTION } from "../workspace-state.ts";
22
-
23
- const target = {
24
- workspaceName: "workspace.alpha-2",
25
- semanticPaneId: "pane.codex_worker-3",
26
- };
27
-
28
- function request() {
29
- return {
30
- protocolVersion: TERMINAL_ATTACHMENT_PROTOCOL_VERSION,
31
- target,
32
- viewerMode: "interactive" as const,
33
- viewport: { cols: 120, rows: 40 },
34
- };
35
- }
36
-
37
- describe("terminal attachment contracts", () => {
38
- it("publishes one shared issue and redemption endpoint authority", () => {
39
- expect(TERMINAL_ATTACHMENT_ISSUE_PATH).toBe("/api/v1/terminal/attachments/issue");
40
- expect(TERMINAL_ATTACHMENT_REDEEM_PATH).toBe("/v1/terminal/attachments/redeem");
41
- });
42
-
43
- it("accepts alternate semantic ids and both viewer modes", () => {
44
- expect(TerminalAttachRequestSchemaZ.parse(request()).target).toEqual(target);
45
- expect(
46
- TerminalAttachRequestSchemaZ.safeParse({ ...request(), viewerMode: "read-only" }).success,
47
- ).toBe(true);
48
- });
49
-
50
- it("defaults an unstated geometry ownership to passive", () => {
51
- /*
52
- * Bug this catches: a caller that predates the field, or forgets it, starts
53
- * driving the size of a tmux window that an ssh client or a colleague is
54
- * also attached to. The unsafe direction has to be the one you ask for.
55
- */
56
- expect(TerminalAttachRequestSchemaZ.parse(request()).geometryOwnership).toBe("passive");
57
- expect(
58
- TerminalAttachRequestSchemaZ.parse({ ...request(), geometryOwnership: "owner" })
59
- .geometryOwnership,
60
- ).toBe("owner");
61
- });
62
-
63
- it("refuses a read-only attachment that asks to own geometry", () => {
64
- /*
65
- * `attach-session -r` implies `ignore-size`, so tmux would drop the request
66
- * on the floor. Accepting it would leave a caller believing it owns a size
67
- * it does not, with nothing anywhere saying otherwise.
68
- */
69
- expect(
70
- TerminalAttachRequestSchemaZ.safeParse({
71
- ...request(),
72
- viewerMode: "read-only",
73
- geometryOwnership: "owner",
74
- }).success,
75
- ).toBe(false);
76
- expect(
77
- TerminalAttachRequestSchemaZ.safeParse({
78
- ...request(),
79
- viewerMode: "read-only",
80
- geometryOwnership: "passive",
81
- }).success,
82
- ).toBe(true);
83
- });
84
-
85
- it("reserves discovered fallback ids outside attachment authority", () => {
86
- const reserved = "terminal.discovered.user-authored";
87
- expect(TerminalAttachmentSemanticPaneIdSchemaZ.safeParse(reserved).success).toBe(false);
88
- expect(
89
- TerminalAttachRequestSchemaZ.safeParse({
90
- ...request(),
91
- target: { ...target, semanticPaneId: reserved },
92
- }).success,
93
- ).toBe(false);
94
- });
95
-
96
- it("shares the pane-stamp grammar for the durable window-id stamp", () => {
97
- expect(WORKSPACE_SEMANTIC_WINDOW_OPTION).toBe("@tmux_ide_window_id");
98
- expect(
99
- TerminalAttachmentSemanticWindowIdSchemaZ.safeParse("window.workspace.alpha").success,
100
- ).toBe(true);
101
- expect(
102
- TerminalAttachmentSemanticWindowIdSchemaZ.safeParse("window.promoted.abc123").success,
103
- ).toBe(true);
104
- for (const invalid of ["terminal.discovered.window", "window:colon", "__proto__", ".dot"]) {
105
- expect(TerminalAttachmentSemanticWindowIdSchemaZ.safeParse(invalid).success).toBe(false);
106
- }
107
- });
108
-
109
- it("uses the exact portable workspace-id grammar for semantic pane admission", () => {
110
- for (const semanticPaneId of [
111
- "pane:colon",
112
- "constructor",
113
- "__proto__",
114
- ".leading-dot",
115
- `pane.${"x".repeat(124)}`,
116
- ]) {
117
- expect(TerminalAttachmentSemanticPaneIdSchemaZ.safeParse(semanticPaneId).success).toBe(false);
118
- expect(
119
- TerminalAttachRequestSchemaZ.safeParse({
120
- ...request(),
121
- target: { ...target, semanticPaneId },
122
- }).success,
123
- ).toBe(false);
124
- }
125
- });
126
-
127
- it("enforces fixed integer viewport limits", () => {
128
- for (const viewport of [
129
- { cols: TERMINAL_ATTACHMENT_MIN_COLS - 1, rows: 40 },
130
- { cols: TERMINAL_ATTACHMENT_MAX_COLS + 1, rows: 40 },
131
- { cols: 120, rows: TERMINAL_ATTACHMENT_MIN_ROWS - 1 },
132
- { cols: 120, rows: TERMINAL_ATTACHMENT_MAX_ROWS + 1 },
133
- { cols: 120.5, rows: 40 },
134
- ]) {
135
- expect(TerminalAttachRequestSchemaZ.safeParse({ ...request(), viewport }).success).toBe(
136
- false,
137
- );
138
- }
139
- expect(
140
- TerminalAttachRequestSchemaZ.safeParse({
141
- ...request(),
142
- viewport: { cols: TERMINAL_ATTACHMENT_MAX_COLS, rows: TERMINAL_ATTACHMENT_MAX_ROWS },
143
- }).success,
144
- ).toBe(true);
145
- });
146
-
147
- it("rejects renderer-supplied execution, runtime-target, and credential fields", () => {
148
- for (const forbidden of [
149
- { cmd: "sh -c whoami" },
150
- { command: "codex --yolo" },
151
- { cwd: "/tmp" },
152
- { paneId: "%7" },
153
- { tmuxTarget: "owner:@9" },
154
- { authToken: "secret" },
155
- ]) {
156
- expect(TerminalAttachRequestSchemaZ.safeParse({ ...request(), ...forbidden }).success).toBe(
157
- false,
158
- );
159
- }
160
- expect(
161
- TerminalAttachRequestSchemaZ.safeParse({
162
- ...request(),
163
- target: { ...target, paneId: "%7" },
164
- }).success,
165
- ).toBe(false);
166
- });
167
-
168
- it("rejects protocol drift and hostile values instead of treating them as targets", () => {
169
- expect(
170
- TerminalAttachRequestSchemaZ.safeParse({ ...request(), protocolVersion: 2 }).success,
171
- ).toBe(false);
172
- for (const hostile of ["%7", "owner:@1", "$(touch-pwned)", "pane;kill-server"] as const) {
173
- expect(
174
- TerminalAttachRequestSchemaZ.safeParse({
175
- ...request(),
176
- target: { ...target, workspaceName: hostile },
177
- }).success,
178
- ).toBe(false);
179
- }
180
- });
181
-
182
- it("keeps planning responses non-redeemable, strict, and renderer-safe", () => {
183
- const response = {
184
- ok: true as const,
185
- protocolVersion: TERMINAL_ATTACHMENT_PROTOCOL_VERSION,
186
- descriptor: {
187
- attachmentId: "2ddc3f17-723b-4e16-a3d2-ad751fb01b2e",
188
- target,
189
- viewerMode: "interactive" as const,
190
- geometryOwnership: "passive" as const,
191
- viewport: { cols: 120, rows: 40 },
192
- status: "planned" as const,
193
- },
194
- handle: {
195
- requestId: "2a215cf2-547e-42a2-91c7-454df8e56121",
196
- },
197
- };
198
- expect(TerminalAttachmentPlanResponseSchemaZ.parse(response)).toEqual(response);
199
- for (const forbidden of [
200
- { authToken: "secret" },
201
- { tmuxTarget: "owner:@7" },
202
- { paneId: "%7" },
203
- { command: "tmux attach" },
204
- { cwd: "/repo" },
205
- ]) {
206
- expect(
207
- TerminalAttachmentPlanResponseSchemaZ.safeParse({
208
- ...response,
209
- descriptor: { ...response.descriptor, ...forbidden },
210
- }).success,
211
- ).toBe(false);
212
- }
213
-
214
- for (const forbidden of [
215
- { ticket: "redeem-me" },
216
- { ticketId: "2a215cf2-547e-42a2-91c7-454df8e56121" },
217
- { token: "secret" },
218
- { auth: "secret" },
219
- { authToken: "secret" },
220
- ]) {
221
- expect(
222
- TerminalAttachmentPlanResponseSchemaZ.safeParse({ ...response, ...forbidden }).success,
223
- ).toBe(false);
224
- }
225
-
226
- expect(
227
- TerminalAttachmentErrorSchemaZ.safeParse({
228
- code: "pane-not-attachable",
229
- message: "The pane belongs to a split window",
230
- target,
231
- reason: "not-single-pane-window",
232
- retryable: false,
233
- }).success,
234
- ).toBe(true);
235
- expect(
236
- TerminalAttachmentErrorSchemaZ.safeParse({
237
- code: "protocol-version-unsupported",
238
- message: "Upgrade required",
239
- receivedVersion: 2,
240
- supportedVersions: [TERMINAL_ATTACHMENT_PROTOCOL_VERSION],
241
- retryable: false,
242
- }).success,
243
- ).toBe(true);
244
- });
245
-
246
- it("accepts one strict, bounded, loopback-only issue descriptor", () => {
247
- const descriptor = {
248
- protocolVersion: TERMINAL_ATTACHMENT_PROTOCOL_VERSION,
249
- webSocketUrl: "ws://127.0.0.1:6060/v1/terminal/attachments/redeem",
250
- subprotocol: TERMINAL_ATTACHMENT_WEBSOCKET_SUBPROTOCOL,
251
- redemptionTicket: `ta1_${"A".repeat(43)}`,
252
- daemonInstanceId: "9bcf33b0-c837-4a94-b5e8-c0977f54464f",
253
- requestId: "10000000-0000-4000-8000-000000000001",
254
- expiresAt: 1_784_662_860_000,
255
- effectiveViewerMode: "interactive" as const,
256
- effectiveGeometryOwnership: "passive" as const,
257
- };
258
- expect(TerminalAttachmentIssueDescriptorSchemaZ.parse(descriptor)).toEqual(descriptor);
259
- expect(TerminalAttachmentIssueResultSchemaZ.parse({ status: "issued", descriptor })).toEqual({
260
- status: "issued",
261
- descriptor,
262
- });
263
-
264
- for (const webSocketUrl of [
265
- "wss://127.0.0.1:6060/v1/terminal/attachments/redeem",
266
- "ws://192.0.2.1:6060/v1/terminal/attachments/redeem",
267
- "ws://secret@127.0.0.1:6060/v1/terminal/attachments/redeem",
268
- "ws://127.0.0.1/v1/terminal/attachments/redeem",
269
- "ws://127.0.0.1:6060/v1/terminal/attachments/redeem?token=secret",
270
- "ws://127.0.0.1:6060/another-path",
271
- ]) {
272
- expect(
273
- TerminalAttachmentIssueDescriptorSchemaZ.safeParse({ ...descriptor, webSocketUrl }).success,
274
- ).toBe(false);
275
- }
276
-
277
- for (const forbidden of [
278
- { tmuxPaneId: "%7" },
279
- { sessionName: "raw-session" },
280
- { cwd: "/private/project" },
281
- { argv: ["codex", "--yolo"] },
282
- { env: { SECRET: "value" } },
283
- { ownerToken: "secret" },
284
- ]) {
285
- expect(
286
- TerminalAttachmentIssueDescriptorSchemaZ.safeParse({ ...descriptor, ...forbidden }).success,
287
- ).toBe(false);
288
- }
289
- });
290
-
291
- it("keeps host-authored issue metadata outside renderer intent", () => {
292
- const mutation = TerminalAttachmentIssueMutationRequestSchemaZ.parse({
293
- requestId: "10000000-0000-4000-8000-000000000001",
294
- expectedDaemonInstanceId: "9bcf33b0-c837-4a94-b5e8-c0977f54464f",
295
- attachment: request(),
296
- });
297
- expect(mutation.attachment).not.toHaveProperty("requestId");
298
- expect(mutation.attachment).not.toHaveProperty("expectedDaemonInstanceId");
299
- expect(
300
- TerminalAttachmentIssueMutationRequestSchemaZ.safeParse({
301
- ...mutation,
302
- origin: "https://renderer.example",
303
- }).success,
304
- ).toBe(false);
305
- });
306
-
307
- it("rejects credential-bearing public error text", () => {
308
- expect(
309
- TerminalAttachmentIssueErrorSchemaZ.parse({
310
- code: "attachment-unavailable",
311
- reason: "The terminal attachment is unavailable.",
312
- retryable: true,
313
- }),
314
- ).toMatchObject({ code: "attachment-unavailable" });
315
- for (const reason of [
316
- "Authorization was Bearer owner-secret",
317
- `The redemptionTicket was ta1_${"A".repeat(43)}`,
318
- "ownerToken=secret",
319
- ]) {
320
- expect(
321
- TerminalAttachmentIssueErrorSchemaZ.safeParse({
322
- code: "request-failed",
323
- reason,
324
- retryable: false,
325
- }).success,
326
- ).toBe(false);
327
- }
328
- });
329
- });
@@ -1,88 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import {
3
- TerminalDeliveryEnvelopeSchemaZ,
4
- TerminalDeliveryNegotiatedSchemaZ,
5
- TerminalDeliveryOfferSchemaZ,
6
- } from "../terminal-delivery.ts";
7
-
8
- const address = {
9
- workspaceName: "workspace",
10
- semanticPaneId: "pane-a",
11
- generation: "00000000-0000-4000-8000-000000000001",
12
- incarnation: "incarnation:1",
13
- deliveryNonce: "00000000-0000-4000-8000-000000000002",
14
- } as const;
15
-
16
- describe("terminal delivery contracts", () => {
17
- it("rejects duplicate negotiation offers and impossible capabilities", () => {
18
- expect(() =>
19
- TerminalDeliveryOfferSchemaZ.parse({
20
- protocolVersions: [1, 1],
21
- encodings: ["semantic-v1"],
22
- richPlacements: false,
23
- }),
24
- ).toThrow();
25
- expect(() =>
26
- TerminalDeliveryNegotiatedSchemaZ.parse({
27
- protocolVersion: 1,
28
- encoding: "ansi-diff-v1",
29
- richPlacements: true,
30
- generation: address.generation,
31
- deliveryNonce: address.deliveryNonce,
32
- }),
33
- ).toThrow();
34
- });
35
-
36
- it("binds chunk count, base revision, equivalence, history and rich claims", () => {
37
- const valid = {
38
- type: "terminal.delivery",
39
- ...address,
40
- transactionId: "00000000-0000-4000-8000-000000000003",
41
- performanceTraceId: "00000000-0000-4000-8000-000000000004",
42
- protocolVersion: 1,
43
- encoding: "semantic-v1",
44
- frame: "seed",
45
- baseRevision: null,
46
- canonicalRevision: 0,
47
- canonicalStateHash: "0000000000000000",
48
- representationHash: "0000000000000000",
49
- representationBytes: 0,
50
- chunkCount: 1,
51
- canonicalEquivalent: true,
52
- history: "complete",
53
- richPlacements: false,
54
- } as const;
55
- expect(TerminalDeliveryEnvelopeSchemaZ.parse(valid)).toEqual(valid);
56
- expect(() =>
57
- TerminalDeliveryEnvelopeSchemaZ.parse({ ...valid, performanceTraceId: "not-a-uuid" }),
58
- ).toThrow();
59
- for (const mutation of [
60
- { chunkCount: 2 },
61
- { baseRevision: 0 },
62
- { canonicalEquivalent: false },
63
- { history: "truncated" },
64
- ])
65
- expect(() => TerminalDeliveryEnvelopeSchemaZ.parse({ ...valid, ...mutation })).toThrow();
66
- });
67
-
68
- it("allows canonical tombstones only with no history", () => {
69
- const tombstone = {
70
- type: "terminal.delivery",
71
- ...address,
72
- transactionId: "00000000-0000-4000-8000-000000000003",
73
- protocolVersion: 1,
74
- encoding: "semantic-v1",
75
- frame: "tombstone",
76
- baseRevision: 0,
77
- canonicalRevision: 1,
78
- canonicalStateHash: "0000000000000000",
79
- representationHash: "0000000000000000",
80
- representationBytes: 0,
81
- chunkCount: 1,
82
- canonicalEquivalent: true,
83
- history: "not-applicable",
84
- richPlacements: false,
85
- } as const;
86
- expect(TerminalDeliveryEnvelopeSchemaZ.parse(tombstone).history).toBe("not-applicable");
87
- });
88
- });
@@ -1,68 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
-
3
- import {
4
- TerminalRuntimeInventoryProjectionV1SchemaZ,
5
- TerminalRuntimeInventoryResourceV1SchemaZ,
6
- } from "../terminal-runtime-inventory.ts";
7
- import { DAEMON_WIRE_PROTOCOL_VERSION } from "../daemon-wire.ts";
8
-
9
- const daemon = {
10
- protocolVersion: DAEMON_WIRE_PROTOCOL_VERSION,
11
- productVersion: "1.0.0",
12
- instanceId: "123e4567-e89b-42d3-a456-426614174000",
13
- startedAt: "2026-08-17T10:00:00.000Z",
14
- };
15
-
16
- describe("terminal runtime inventory contract", () => {
17
- it("accepts only sorted semantic topology with opaque product/session identities", () => {
18
- expect(
19
- TerminalRuntimeInventoryResourceV1SchemaZ.parse({
20
- version: 1,
21
- daemon,
22
- resource: {
23
- workspaceName: "alpha",
24
- workspaceId: "workspace.0123456789abcdefabcd",
25
- sessionId: "session.0123456789abcdefabcd",
26
- resourceRevision: 4,
27
- semanticPaneIds: ["pane.a", "pane.b"],
28
- },
29
- }).resource.semanticPaneIds,
30
- ).toEqual(["pane.a", "pane.b"]);
31
- });
32
-
33
- it.each(["$3", "/Users/person/project", "session\nsecret", "plain-session"])(
34
- "rejects raw/control/path session identity %j",
35
- (sessionId) => {
36
- expect(
37
- TerminalRuntimeInventoryProjectionV1SchemaZ.safeParse({
38
- workspaceName: "alpha",
39
- workspaceId: "workspace.0123456789abcdefabcd",
40
- sessionId,
41
- resourceRevision: 0,
42
- semanticPaneIds: [],
43
- }).success,
44
- ).toBe(false);
45
- },
46
- );
47
-
48
- it("rejects duplicate or unsorted pane identities", () => {
49
- const base = {
50
- workspaceName: "alpha",
51
- workspaceId: "workspace.0123456789abcdefabcd",
52
- sessionId: "session.0123456789abcdefabcd",
53
- resourceRevision: 0,
54
- };
55
- expect(
56
- TerminalRuntimeInventoryProjectionV1SchemaZ.safeParse({
57
- ...base,
58
- semanticPaneIds: ["pane.b", "pane.a"],
59
- }).success,
60
- ).toBe(false);
61
- expect(
62
- TerminalRuntimeInventoryProjectionV1SchemaZ.safeParse({
63
- ...base,
64
- semanticPaneIds: ["pane.a", "pane.a"],
65
- }).success,
66
- ).toBe(false);
67
- });
68
- });
@@ -1,87 +0,0 @@
1
- /**
2
- * `createScriptTerminalId` determinism tests (G20-P1).
3
- *
4
- * The whole point of the script-derived id is determinism — two
5
- * callers asking for "the run script for project X, scope Y, script
6
- * Z" must collapse to one bridge. These tests pin that contract.
7
- */
8
-
9
- import { describe, expect, it } from "vitest";
10
- import { createScriptTerminalId } from "../terminals";
11
-
12
- describe("createScriptTerminalId", () => {
13
- it("is deterministic for the same input", async () => {
14
- const a = await createScriptTerminalId({
15
- projectId: "proj",
16
- scopeId: "feat-x",
17
- kind: "run",
18
- script: "pnpm dev",
19
- });
20
- const b = await createScriptTerminalId({
21
- projectId: "proj",
22
- scopeId: "feat-x",
23
- kind: "run",
24
- script: "pnpm dev",
25
- });
26
- expect(a).toBe(b);
27
- expect(a).toHaveLength(32);
28
- });
29
-
30
- it("changes when scopeId changes (same project + script)", async () => {
31
- const a = await createScriptTerminalId({
32
- projectId: "proj",
33
- scopeId: "feat-x",
34
- kind: "run",
35
- script: "pnpm dev",
36
- });
37
- const b = await createScriptTerminalId({
38
- projectId: "proj",
39
- scopeId: "feat-y",
40
- kind: "run",
41
- script: "pnpm dev",
42
- });
43
- expect(a).not.toBe(b);
44
- });
45
-
46
- it("changes when kind changes", async () => {
47
- const run = await createScriptTerminalId({
48
- projectId: "proj",
49
- scopeId: "feat-x",
50
- kind: "run",
51
- script: "pnpm dev",
52
- });
53
- const setup = await createScriptTerminalId({
54
- projectId: "proj",
55
- scopeId: "feat-x",
56
- kind: "setup",
57
- script: "pnpm dev",
58
- });
59
- expect(run).not.toBe(setup);
60
- });
61
-
62
- it("accepts taskId as a backward-compat alias for scopeId", async () => {
63
- const viaScope = await createScriptTerminalId({
64
- projectId: "proj",
65
- scopeId: "feat-x",
66
- kind: "run",
67
- script: "pnpm dev",
68
- });
69
- const viaTask = await createScriptTerminalId({
70
- projectId: "proj",
71
- taskId: "feat-x",
72
- kind: "run",
73
- script: "pnpm dev",
74
- });
75
- expect(viaScope).toBe(viaTask);
76
- });
77
-
78
- it("rejects calls without scope or task", async () => {
79
- await expect(
80
- createScriptTerminalId({
81
- projectId: "proj",
82
- kind: "run",
83
- script: "pnpm dev",
84
- }),
85
- ).rejects.toThrow(/scopeId/);
86
- });
87
- });