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,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
- });