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,409 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
-
3
- import {
4
- STARTUP_READINESS_RESOURCE_VERSION,
5
- STARTUP_READINESS_RUNG_ORDER,
6
- StartupReadinessLadderSchemaZ,
7
- StartupReadinessResourceSchemaZ,
8
- StartupReadinessRungSchemaZ,
9
- buildStartupReadinessLadder,
10
- projectDesktopStartupReadiness,
11
- startupReadinessBlockingRung,
12
- type StartupReadinessLadder,
13
- } from "../startup-readiness.ts";
14
- import {
15
- DaemonChildOutputTailSchemaZ,
16
- DesktopDaemonCapabilityStateSchemaZ,
17
- type DaemonChildOutputTail,
18
- } from "../desktop-host.ts";
19
-
20
- const OBSERVED_AT = "2026-08-04T12:00:00.000Z";
21
-
22
- const IDENTITY = {
23
- protocolVersion: 1,
24
- productVersion: "2.7.0",
25
- instanceId: "0f5a2a3e-6f0a-4f1a-9f2b-1c2d3e4f5a6b",
26
- startedAt: "2026-08-04T11:59:00.000Z",
27
- } as const;
28
-
29
- function fullyWalked(): StartupReadinessLadder {
30
- return buildStartupReadinessLadder(
31
- [
32
- { status: "satisfied" },
33
- { status: "satisfied" },
34
- { status: "satisfied" },
35
- {
36
- status: "satisfied",
37
- population: { fleet: "populated", workspaceCount: 2, attachablePaneCount: 3 },
38
- },
39
- { status: "satisfied" },
40
- ],
41
- OBSERVED_AT,
42
- );
43
- }
44
-
45
- describe("startup readiness ladder", () => {
46
- it("walks every rung to satisfied with nothing blocking", () => {
47
- const ladder = fullyWalked();
48
- expect(ladder.rungs.map((rung) => rung.rung)).toEqual([...STARTUP_READINESS_RUNG_ORDER]);
49
- expect(ladder.rungs.every((rung) => rung.status === "satisfied")).toBe(true);
50
- expect(ladder.blockedAt).toBeNull();
51
- expect(startupReadinessBlockingRung(ladder)).toBeNull();
52
- expect(StartupReadinessLadderSchemaZ.safeParse(ladder).success).toBe(true);
53
- });
54
-
55
- it("stops the ladder at the stuck rung and leaves everything above it pending", () => {
56
- const ladder = buildStartupReadinessLadder(
57
- [
58
- { status: "satisfied" },
59
- { status: "satisfied" },
60
- { status: "satisfied" },
61
- {
62
- status: "stuck",
63
- reason: { vocabulary: "terminal-resource-unavailable", code: "missing-semantic-stamp" },
64
- },
65
- // A verdict past the blocking rung is ignored; it cannot be believed.
66
- { status: "satisfied" },
67
- ],
68
- OBSERVED_AT,
69
- );
70
- expect(ladder.blockedAt).toBe("catalog-populated");
71
- expect(ladder.rungs[3]).toEqual({
72
- rung: "catalog-populated",
73
- status: "stuck",
74
- observedAt: OBSERVED_AT,
75
- reason: { vocabulary: "terminal-resource-unavailable", code: "missing-semantic-stamp" },
76
- });
77
- expect(ladder.rungs[4]!.status).toBe("pending");
78
- expect(StartupReadinessLadderSchemaZ.safeParse(ladder).success).toBe(true);
79
- });
80
-
81
- it("fills unproven rungs as pending when the caller supplies fewer verdicts", () => {
82
- const ladder = buildStartupReadinessLadder([{ status: "satisfied" }], OBSERVED_AT);
83
- expect(ladder.blockedAt).toBe("credential-held");
84
- expect(ladder.rungs.slice(1).every((rung) => rung.status === "pending")).toBe(true);
85
- });
86
-
87
- it("rejects a ladder that claims a satisfied rung above an unsatisfied one", () => {
88
- const ladder = fullyWalked();
89
- const broken = {
90
- ...ladder,
91
- rungs: [
92
- ladder.rungs[0]!,
93
- { rung: "credential-held", status: "pending", observedAt: OBSERVED_AT },
94
- ...ladder.rungs.slice(2),
95
- ],
96
- blockedAt: "credential-held",
97
- };
98
- const result = StartupReadinessLadderSchemaZ.safeParse(broken);
99
- expect(result.success).toBe(false);
100
- expect(JSON.stringify(result.error?.issues)).toContain(
101
- "a rung cannot be satisfied above an unsatisfied rung",
102
- );
103
- });
104
-
105
- it("rejects a blockedAt that does not name the first unsatisfied rung", () => {
106
- const ladder = buildStartupReadinessLadder([{ status: "satisfied" }], OBSERVED_AT);
107
- const result = StartupReadinessLadderSchemaZ.safeParse({
108
- ...ladder,
109
- blockedAt: "attachment-issuable",
110
- });
111
- expect(result.success).toBe(false);
112
- });
113
-
114
- it("rejects rungs presented out of canonical order", () => {
115
- const ladder = fullyWalked();
116
- const result = StartupReadinessLadderSchemaZ.safeParse({
117
- ...ladder,
118
- rungs: [ladder.rungs[1]!, ladder.rungs[0]!, ...ladder.rungs.slice(2)],
119
- });
120
- expect(result.success).toBe(false);
121
- });
122
-
123
- it("rejects a stuck reason drawn from a vocabulary that cannot explain the rung", () => {
124
- const result = StartupReadinessRungSchemaZ.safeParse({
125
- rung: "catalog-populated",
126
- status: "stuck",
127
- observedAt: OBSERVED_AT,
128
- reason: { vocabulary: "desktop-daemon-host-issue", code: "probe-timeout" },
129
- });
130
- expect(result.success).toBe(false);
131
- expect(JSON.stringify(result.error?.issues)).toContain("cannot be explained by");
132
- });
133
-
134
- it("accepts each rung's own vocabulary", () => {
135
- const accepted = [
136
- {
137
- rung: "daemon-spawned",
138
- reason: { vocabulary: "desktop-daemon-host-issue", code: "process-not-running" },
139
- },
140
- {
141
- rung: "credential-held",
142
- reason: { vocabulary: "startup-readiness", code: "owner-capability-unavailable" },
143
- },
144
- {
145
- rung: "identity-established",
146
- reason: { vocabulary: "desktop-daemon-host-issue", code: "identity-mismatch" },
147
- },
148
- {
149
- rung: "catalog-populated",
150
- reason: { vocabulary: "startup-readiness", code: "catalog-discovery-failed" },
151
- },
152
- {
153
- rung: "attachment-issuable",
154
- reason: { vocabulary: "terminal-attachment-issue", code: "attachment-unavailable" },
155
- },
156
- ] as const;
157
- for (const { rung, reason } of accepted) {
158
- expect(
159
- StartupReadinessRungSchemaZ.safeParse({
160
- rung,
161
- status: "stuck",
162
- observedAt: OBSERVED_AT,
163
- reason,
164
- }).success,
165
- ).toBe(true);
166
- }
167
- });
168
- });
169
-
170
- describe("empty fleet versus stuck", () => {
171
- it("treats a catalog with no workspaces as satisfied, not stuck", () => {
172
- const ladder = buildStartupReadinessLadder(
173
- [
174
- { status: "satisfied" },
175
- { status: "satisfied" },
176
- { status: "satisfied" },
177
- {
178
- status: "satisfied",
179
- population: { fleet: "empty", workspaceCount: 0, attachablePaneCount: 0 },
180
- },
181
- { status: "satisfied" },
182
- ],
183
- OBSERVED_AT,
184
- );
185
- expect(ladder.blockedAt).toBeNull();
186
- const catalogRung = ladder.rungs[3]!;
187
- expect(catalogRung.status).toBe("satisfied");
188
- expect(catalogRung.status === "satisfied" ? catalogRung.population : null).toEqual({
189
- fleet: "empty",
190
- workspaceCount: 0,
191
- attachablePaneCount: 0,
192
- });
193
- expect(StartupReadinessLadderSchemaZ.safeParse(ladder).success).toBe(true);
194
- });
195
-
196
- it("rejects an 'empty' fleet that reports workspaces, or a populated one with none", () => {
197
- const base = {
198
- rung: "catalog-populated",
199
- status: "satisfied",
200
- observedAt: OBSERVED_AT,
201
- } as const;
202
- expect(
203
- StartupReadinessRungSchemaZ.safeParse({
204
- ...base,
205
- population: { fleet: "empty", workspaceCount: 2, attachablePaneCount: 0 },
206
- }).success,
207
- ).toBe(false);
208
- expect(
209
- StartupReadinessRungSchemaZ.safeParse({
210
- ...base,
211
- population: { fleet: "populated", workspaceCount: 0, attachablePaneCount: 0 },
212
- }).success,
213
- ).toBe(false);
214
- });
215
-
216
- it("rejects catalog population claimed on any other rung", () => {
217
- expect(
218
- StartupReadinessRungSchemaZ.safeParse({
219
- rung: "attachment-issuable",
220
- status: "satisfied",
221
- observedAt: OBSERVED_AT,
222
- population: { fleet: "empty", workspaceCount: 0, attachablePaneCount: 0 },
223
- }).success,
224
- ).toBe(false);
225
- });
226
- });
227
-
228
- describe("startup readiness resource", () => {
229
- it("carries the daemon generation stamp alongside the ladder", () => {
230
- const parsed = StartupReadinessResourceSchemaZ.safeParse({
231
- version: STARTUP_READINESS_RESOURCE_VERSION,
232
- daemon: IDENTITY,
233
- ladder: fullyWalked(),
234
- });
235
- expect(parsed.success).toBe(true);
236
- });
237
- });
238
-
239
- describe("desktop projection", () => {
240
- const childOutput: DaemonChildOutputTail = {
241
- stream: "stderr",
242
- lines: ["Error: listen EADDRINUSE: address already in use 127.0.0.1:8787"],
243
- truncated: false,
244
- exitCode: 1,
245
- signal: null,
246
- };
247
-
248
- it("names daemon-spawned as the stuck rung and carries the child's own words", () => {
249
- const readiness = projectDesktopStartupReadiness({
250
- daemon: {
251
- status: "unavailable",
252
- code: "process-not-running",
253
- reason: "The canonical daemon is unavailable.",
254
- childOutput,
255
- },
256
- ladder: null,
257
- observedAt: OBSERVED_AT,
258
- });
259
- expect(readiness.ladder.blockedAt).toBe("daemon-spawned");
260
- expect(readiness.ladder.rungs[0]).toEqual({
261
- rung: "daemon-spawned",
262
- status: "stuck",
263
- observedAt: OBSERVED_AT,
264
- reason: { vocabulary: "desktop-daemon-host-issue", code: "process-not-running" },
265
- });
266
- expect(readiness.childOutput).toEqual(childOutput);
267
- expect(DaemonChildOutputTailSchemaZ.safeParse(readiness.childOutput).success).toBe(true);
268
- expect(StartupReadinessLadderSchemaZ.safeParse(readiness.ladder).success).toBe(true);
269
- });
270
-
271
- it("carries a halted supervisor through as the daemon-spawned reason", () => {
272
- const readiness = projectDesktopStartupReadiness({
273
- daemon: {
274
- status: "degraded",
275
- code: "supervisor-halted",
276
- reason: "The bundled engine stopped after 3 consecutive fatal startup failures.",
277
- },
278
- ladder: null,
279
- observedAt: OBSERVED_AT,
280
- });
281
- expect(readiness.ladder.blockedAt).toBe("daemon-spawned");
282
- expect(readiness.childOutput).toBeUndefined();
283
- });
284
-
285
- it("proves the first three rungs from a connected host state alone", () => {
286
- const readiness = projectDesktopStartupReadiness({
287
- daemon: { status: "connected", identity: IDENTITY },
288
- ladder: null,
289
- observedAt: OBSERVED_AT,
290
- });
291
- expect(readiness.ladder.blockedAt).toBe("catalog-populated");
292
- expect(readiness.ladder.rungs.slice(0, 3).every((rung) => rung.status === "satisfied")).toBe(
293
- true,
294
- );
295
- expect(readiness.ladder.rungs[3]!.status).toBe("pending");
296
- });
297
-
298
- it("defers to the daemon's own ladder once it has been read", () => {
299
- const ladder = fullyWalked();
300
- const readiness = projectDesktopStartupReadiness({
301
- daemon: { status: "connected", identity: IDENTITY },
302
- ladder,
303
- observedAt: OBSERVED_AT,
304
- });
305
- expect(readiness.ladder).toEqual(ladder);
306
- });
307
-
308
- it("prefers a ladder carried on a disconnected state over the host's outside view", () => {
309
- // The daemon answers, but this desktop cannot use that generation. Only the
310
- // daemon can see that the catalog is what is actually stuck.
311
- const ladder = buildStartupReadinessLadder(
312
- [
313
- { status: "satisfied" },
314
- { status: "satisfied" },
315
- { status: "satisfied" },
316
- {
317
- status: "stuck",
318
- reason: { vocabulary: "terminal-resource-unavailable", code: "missing-semantic-stamp" },
319
- },
320
- ],
321
- OBSERVED_AT,
322
- );
323
- const readiness = projectDesktopStartupReadiness({
324
- daemon: {
325
- status: "degraded",
326
- code: "identity-mismatch",
327
- reason: "Canonical daemon verification is degraded.",
328
- startupReadiness: ladder,
329
- },
330
- observedAt: OBSERVED_AT,
331
- });
332
- expect(readiness.ladder.blockedAt).toBe("catalog-populated");
333
- expect(readiness.ladder).toEqual(ladder);
334
- });
335
-
336
- it("keeps the host issue when the daemon's own ladder claims everything is fine", () => {
337
- // A daemon that believes it is healthy explains nothing about why THIS
338
- // desktop is disconnected, so the host's observation stays the answer.
339
- const readiness = projectDesktopStartupReadiness({
340
- daemon: {
341
- status: "degraded",
342
- code: "identity-mismatch",
343
- reason: "Canonical daemon verification is degraded.",
344
- startupReadiness: fullyWalked(),
345
- },
346
- observedAt: OBSERVED_AT,
347
- });
348
- expect(readiness.ladder.blockedAt).toBe("daemon-spawned");
349
- expect(readiness.ladder.rungs[0]).toMatchObject({
350
- status: "stuck",
351
- reason: { vocabulary: "desktop-daemon-host-issue", code: "identity-mismatch" },
352
- });
353
- });
354
-
355
- it("carries the child output alongside a preferred daemon ladder", () => {
356
- const childOutput: DaemonChildOutputTail = {
357
- stream: "stderr",
358
- lines: ["tmux: server exited"],
359
- truncated: false,
360
- exitCode: 1,
361
- signal: null,
362
- };
363
- const readiness = projectDesktopStartupReadiness({
364
- daemon: {
365
- status: "unavailable",
366
- code: "probe-failed",
367
- reason: "The canonical daemon is unavailable.",
368
- childOutput,
369
- startupReadiness: buildStartupReadinessLadder(
370
- [
371
- { status: "satisfied" },
372
- { status: "satisfied" },
373
- { status: "satisfied" },
374
- {
375
- status: "stuck",
376
- reason: { vocabulary: "startup-readiness", code: "catalog-sessions-unreachable" },
377
- },
378
- ],
379
- OBSERVED_AT,
380
- ),
381
- },
382
- observedAt: OBSERVED_AT,
383
- });
384
- expect(readiness.ladder.blockedAt).toBe("catalog-populated");
385
- expect(readiness.childOutput).toEqual(childOutput);
386
- });
387
-
388
- it("falls back to the host issue when no ladder could be read at all", () => {
389
- const readiness = projectDesktopStartupReadiness({
390
- daemon: {
391
- status: "unavailable",
392
- code: "process-not-running",
393
- reason: "The canonical daemon is unavailable.",
394
- },
395
- observedAt: OBSERVED_AT,
396
- });
397
- expect(readiness.ladder.blockedAt).toBe("daemon-spawned");
398
- });
399
-
400
- it("accepts a ladder on a disconnected capability state through the wire schema", () => {
401
- const parsed = DesktopDaemonCapabilityStateSchemaZ.safeParse({
402
- status: "degraded",
403
- code: "identity-mismatch",
404
- reason: "Canonical daemon verification is degraded.",
405
- startupReadiness: fullyWalked(),
406
- });
407
- expect(parsed.success).toBe(true);
408
- });
409
- });
@@ -1,72 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import {
3
- TERMINAL_ATTACHMENT_INPUT_FRAME_HEADER_BYTES,
4
- TERMINAL_ATTACHMENT_MAX_INPUT_FRAME_BYTES,
5
- TerminalAttachmentInputAckFrameSchemaZ,
6
- TerminalAttachmentInputCapabilitySchemaZ,
7
- decodeTerminalAttachmentInputFrame,
8
- encodeTerminalAttachmentInputFrame,
9
- } from "../terminal-attachment-stream.ts";
10
-
11
- describe("terminal attachment input wire", () => {
12
- it("round-trips an exact binary payload and big-endian monotonic sequence", () => {
13
- const payload = Uint8Array.of(0, 1, 0x80, 0xff);
14
- const encoded = encodeTerminalAttachmentInputFrame(0x0102_0304, payload);
15
-
16
- expect([...encoded.slice(0, TERMINAL_ATTACHMENT_INPUT_FRAME_HEADER_BYTES)]).toEqual([
17
- 1, 1, 2, 3, 4,
18
- ]);
19
- const decoded = decodeTerminalAttachmentInputFrame(encoded);
20
- expect(decoded?.sequence).toBe(0x0102_0304);
21
- expect(decoded?.payload).toEqual(payload);
22
- });
23
-
24
- it("rejects empty, malformed, zero-sequence, and oversized input without payload reflection", () => {
25
- expect(() => encodeTerminalAttachmentInputFrame(0, Uint8Array.of(1))).toThrow(/sequence/u);
26
- expect(() => encodeTerminalAttachmentInputFrame(1, new Uint8Array())).toThrow(/non-empty/u);
27
- expect(() =>
28
- encodeTerminalAttachmentInputFrame(
29
- 1,
30
- new Uint8Array(TERMINAL_ATTACHMENT_MAX_INPUT_FRAME_BYTES + 1),
31
- ),
32
- ).toThrow(/wire bound/u);
33
- expect(decodeTerminalAttachmentInputFrame(Uint8Array.of(1, 0, 0, 0, 0, 7))).toBeNull();
34
- expect(decodeTerminalAttachmentInputFrame(Uint8Array.of(2, 0, 0, 0, 1, 7))).toBeNull();
35
- });
36
-
37
- it("keeps ready limits and acknowledgements strict and renderer-safe", () => {
38
- const limits = {
39
- maxFrameBytes: 16 * 1024,
40
- maxAcceptedBytes: 256 * 1024,
41
- maxAcceptedFrames: 8_192,
42
- };
43
- expect(TerminalAttachmentInputCapabilitySchemaZ.parse({ mode: "bounded", limits })).toEqual({
44
- mode: "bounded",
45
- limits,
46
- });
47
- expect(
48
- TerminalAttachmentInputCapabilitySchemaZ.safeParse({
49
- mode: "bounded",
50
- limits: { ...limits, maxFrameBytes: limits.maxAcceptedBytes + 1 },
51
- }).success,
52
- ).toBe(false);
53
-
54
- const ack = {
55
- type: "input-ack" as const,
56
- protocolVersion: 1 as const,
57
- generation: 2,
58
- sequence: 3,
59
- byteLength: 4,
60
- state: "open" as const,
61
- acceptedBytes: 12,
62
- acceptedFrames: 3,
63
- remainingBytes: 100,
64
- remainingFrames: 20,
65
- };
66
- expect(TerminalAttachmentInputAckFrameSchemaZ.parse(ack)).toEqual(ack);
67
- expect(
68
- TerminalAttachmentInputAckFrameSchemaZ.safeParse({ ...ack, redemptionTicket: "secret" })
69
- .success,
70
- ).toBe(false);
71
- });
72
- });