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,272 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import {
3
- MissionActorSchemaZ,
4
- MissionAttemptIdSchemaZ,
5
- MissionEventSchemaZ,
6
- MissionIdSchemaZ,
7
- MissionAttemptSchemaZ,
8
- MissionProjectStateSchemaZ,
9
- MissionSnapshotSchemaZ,
10
- MissionProofSchemaZ,
11
- MissionReferenceIdSchemaZ,
12
- MissionStatusSchemaZ,
13
- MissionTaskSchemaZ,
14
- MissionTaskIdSchemaZ,
15
- MissionTaskStatusSchemaZ,
16
- MissionTerminalReferenceSchemaZ,
17
- } from "../domain.ts";
18
-
19
- const actor = { type: "user" as const, id: "pm" };
20
-
21
- describe("mission domain contracts", () => {
22
- it("round-trips provider-neutral mission, task, attempt, and proof events", () => {
23
- const events = [
24
- {
25
- version: 1,
26
- type: "mission.created",
27
- missionId: "mis_alpha",
28
- title: "Ship durable missions",
29
- objective: "Persist mission state",
30
- acceptanceCriteria: ["replayable"],
31
- constraints: ["harness-neutral"],
32
- labels: ["m27"],
33
- source: { type: "user", id: "sfora-card-114" },
34
- actor,
35
- },
36
- {
37
- version: 1,
38
- type: "task.added",
39
- missionId: "mis_alpha",
40
- taskId: "tsk_contracts",
41
- title: "Add contracts",
42
- priority: 1,
43
- dependencies: [],
44
- assignee: "worker.profile",
45
- actor,
46
- },
47
- {
48
- version: 1,
49
- type: "attempt.started",
50
- missionId: "mis_alpha",
51
- taskId: "tsk_contracts",
52
- attemptId: "att_first",
53
- agent: "worker.profile",
54
- harness: "generic-harness",
55
- model: "opaque/model-ref",
56
- terminal: "%7",
57
- session: "session_1",
58
- worktree: "worktrees/task",
59
- actor,
60
- },
61
- {
62
- version: 1,
63
- type: "proof.recorded",
64
- missionId: "mis_alpha",
65
- taskId: "tsk_contracts",
66
- attemptId: "att_first",
67
- proofId: "prf_tests",
68
- proof: {
69
- tests: [{ name: "contracts", status: "passed", passed: 12, total: 12 }],
70
- commits: [{ sha: "abcdef1" }],
71
- diff: { summary: "Added schemas", stats: { filesChanged: 2 } },
72
- pr: { number: 114, status: "open" },
73
- artifacts: [{ name: "log", uri: "runtime://artifact/log" }],
74
- notes: "All checks passed",
75
- },
76
- actor,
77
- },
78
- ];
79
-
80
- for (const event of events) {
81
- expect(MissionEventSchemaZ.parse(event)).toEqual(event);
82
- }
83
- });
84
-
85
- it("rejects malformed IDs, references, statuses, proofs, and event payloads", () => {
86
- expect(MissionIdSchemaZ.safeParse("../mis").success).toBe(false);
87
- expect(MissionTaskIdSchemaZ.safeParse("task-1").success).toBe(false);
88
- expect(MissionAttemptIdSchemaZ.safeParse("att space").success).toBe(false);
89
- expect(MissionReferenceIdSchemaZ.safeParse("../profile").success).toBe(false);
90
- expect(MissionReferenceIdSchemaZ.safeParse("%7").success).toBe(false);
91
- expect(MissionTerminalReferenceSchemaZ.safeParse("%7").success).toBe(true);
92
- expect(MissionTerminalReferenceSchemaZ.safeParse("term_1").success).toBe(true);
93
- for (const value of ["%", "%-1", "%abc", "%7 bad", "%7;send-keys", "%7\n"]) {
94
- expect(MissionTerminalReferenceSchemaZ.safeParse(value).success).toBe(false);
95
- }
96
- expect(MissionTerminalReferenceSchemaZ.safeParse(`%${"7".repeat(21)}`).success).toBe(false);
97
- expect(MissionStatusSchemaZ.safeParse("dispatching").success).toBe(false);
98
- expect(MissionTaskStatusSchemaZ.safeParse("updated").success).toBe(false);
99
- expect(MissionActorSchemaZ.safeParse({ type: "claude" }).success).toBe(false);
100
- expect(MissionProofSchemaZ.safeParse({}).success).toBe(false);
101
- expect(
102
- MissionProofSchemaZ.safeParse({
103
- tests: [{ name: "unit", status: "passed", passed: 2, total: 1 }],
104
- }).success,
105
- ).toBe(false);
106
- expect(MissionProofSchemaZ.safeParse({ tests: [{ name: "", status: "passed" }] }).success).toBe(
107
- false,
108
- );
109
- expect(
110
- MissionEventSchemaZ.safeParse({
111
- version: 2,
112
- type: "mission.created",
113
- missionId: "mis_alpha",
114
- title: "x",
115
- objective: "x",
116
- acceptanceCriteria: [],
117
- constraints: [],
118
- labels: [],
119
- source: { type: "user" },
120
- actor,
121
- }).success,
122
- ).toBe(false);
123
- expect(
124
- MissionEventSchemaZ.safeParse({
125
- version: 1,
126
- type: "provider.claude.spawned",
127
- missionId: "mis_alpha",
128
- actor,
129
- }).success,
130
- ).toBe(false);
131
- });
132
-
133
- it("strictly parses projected task, attempt, and mission snapshots", () => {
134
- const task = {
135
- id: "tsk_contracts",
136
- missionId: "mis_alpha",
137
- title: "Contracts",
138
- priority: 1,
139
- dependencies: [],
140
- status: "completed",
141
- createdAt: "2026-01-01T00:00:00.000Z",
142
- updatedAt: "2026-01-01T00:00:01.000Z",
143
- proofIds: ["prf_tests"],
144
- attemptIds: ["att_first"],
145
- };
146
- const attempt = {
147
- id: "att_first",
148
- missionId: "mis_alpha",
149
- taskId: "tsk_contracts",
150
- agent: "worker",
151
- harness: "generic",
152
- status: "approved",
153
- outcome: "approved",
154
- startedAt: "2026-01-01T00:00:00.000Z",
155
- updatedAt: "2026-01-01T00:00:01.000Z",
156
- proofIds: ["prf_tests"],
157
- };
158
-
159
- expect(MissionTaskSchemaZ.parse(task)).toEqual(task);
160
- expect(MissionAttemptSchemaZ.parse(attempt)).toEqual(attempt);
161
- expect(
162
- MissionSnapshotSchemaZ.parse({
163
- id: "mis_alpha",
164
- title: "Alpha",
165
- objective: "Ship",
166
- acceptanceCriteria: [],
167
- constraints: [],
168
- labels: [],
169
- source: { type: "user" },
170
- status: "completed",
171
- createdAt: "2026-01-01T00:00:00.000Z",
172
- updatedAt: "2026-01-01T00:00:01.000Z",
173
- tasks: { tsk_contracts: task },
174
- attempts: { att_first: attempt },
175
- proofs: { prf_tests: { noProofReason: "manual acceptance" } },
176
- }),
177
- ).toMatchObject({ tasks: { tsk_contracts: { status: "completed" } } });
178
-
179
- expect(MissionTaskSchemaZ.safeParse({ ...task, extra: true }).success).toBe(false);
180
- expect(MissionAttemptSchemaZ.safeParse({ ...attempt, provider: "claude" }).success).toBe(false);
181
- });
182
-
183
- it("rejects projected state with broken keys, references, or duplicate reference arrays", () => {
184
- const validTask = {
185
- id: "tsk_contracts",
186
- missionId: "mis_alpha",
187
- title: "Contracts",
188
- priority: 1,
189
- dependencies: [],
190
- status: "completed",
191
- createdAt: "2026-01-01T00:00:00.000Z",
192
- updatedAt: "2026-01-01T00:00:01.000Z",
193
- proofIds: ["prf_tests"],
194
- attemptIds: ["att_first"],
195
- };
196
- const validAttempt = {
197
- id: "att_first",
198
- missionId: "mis_alpha",
199
- taskId: "tsk_contracts",
200
- agent: "worker",
201
- harness: "generic",
202
- status: "approved",
203
- outcome: "approved",
204
- startedAt: "2026-01-01T00:00:00.000Z",
205
- updatedAt: "2026-01-01T00:00:01.000Z",
206
- proofIds: ["prf_tests"],
207
- };
208
- const validMission = {
209
- id: "mis_alpha",
210
- title: "Alpha",
211
- objective: "Ship",
212
- acceptanceCriteria: [],
213
- constraints: [],
214
- labels: [],
215
- source: { type: "user" },
216
- status: "completed",
217
- createdAt: "2026-01-01T00:00:00.000Z",
218
- updatedAt: "2026-01-01T00:00:01.000Z",
219
- tasks: { tsk_contracts: validTask },
220
- attempts: { att_first: validAttempt },
221
- proofs: { prf_tests: { noProofReason: "manual acceptance" } },
222
- };
223
-
224
- expect(
225
- MissionProjectStateSchemaZ.safeParse({
226
- sequence: 1,
227
- missions: { mis_other: validMission },
228
- }).success,
229
- ).toBe(false);
230
- expect(
231
- MissionSnapshotSchemaZ.safeParse({
232
- ...validMission,
233
- tasks: { tsk_wrong: validTask },
234
- }).success,
235
- ).toBe(false);
236
- expect(
237
- MissionSnapshotSchemaZ.safeParse({
238
- ...validMission,
239
- tasks: {
240
- tsk_contracts: {
241
- ...validTask,
242
- proofIds: ["prf_tests", "prf_tests"],
243
- },
244
- },
245
- }).success,
246
- ).toBe(false);
247
- expect(
248
- MissionSnapshotSchemaZ.safeParse({
249
- ...validMission,
250
- attempts: { att_first: { ...validAttempt, taskId: "tsk_missing" } },
251
- }).success,
252
- ).toBe(false);
253
- expect(
254
- MissionSnapshotSchemaZ.safeParse({
255
- ...validMission,
256
- tasks: {
257
- tsk_contracts: {
258
- ...validTask,
259
- attemptIds: ["att_first"],
260
- },
261
- },
262
- attempts: { att_first: { ...validAttempt, taskId: "tsk_missing" } },
263
- }).success,
264
- ).toBe(false);
265
- expect(
266
- MissionSnapshotSchemaZ.safeParse({
267
- ...validMission,
268
- attempts: { att_first: { ...validAttempt, proofIds: ["prf_missing"] } },
269
- }).success,
270
- ).toBe(false);
271
- });
272
- });
@@ -1,242 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
-
3
- import { ActionContractsZ } from "../actions-contract.ts";
4
- import { AppWindowMutationCommandSchemaZ } from "../app-window-mutation.ts";
5
- import {
6
- MULTIPLEXER_VERB_IDS,
7
- MULTIPLEXER_VERB_TABLE,
8
- MultiplexerVerbEntrySchemaZ,
9
- isMultiplexerVerbId,
10
- multiplexerVerb,
11
- multiplexerVerbAvailability,
12
- multiplexerVerbsForScope,
13
- type MultiplexerVerbEntry,
14
- } from "../multiplexer-verbs.ts";
15
-
16
- const verb = (id: string): MultiplexerVerbEntry => {
17
- const found = MULTIPLEXER_VERB_TABLE.find((entry) => entry.id === id);
18
- if (!found) throw new Error(`missing verb ${id}`);
19
- return found;
20
- };
21
-
22
- describe("the multiplexer verb table", () => {
23
- it("carries every verb the milestone declares, and no others", () => {
24
- expect([...MULTIPLEXER_VERB_IDS]).toEqual([
25
- "window.link.select",
26
- "window.link.unlink",
27
- "session.new",
28
- "session.kill",
29
- "session.rename",
30
- "session.detach",
31
- "window.new",
32
- "window.kill",
33
- "window.rename",
34
- "window.zoom.toggle",
35
- "pane.split.right",
36
- "pane.split.down",
37
- "pane.kill",
38
- "pane.select",
39
- "pane.swap",
40
- "pane.resize",
41
- "stack.activate",
42
- ]);
43
- });
44
-
45
- it("conforms to its own schema", () => {
46
- for (const entry of MULTIPLEXER_VERB_TABLE) {
47
- expect(() => MultiplexerVerbEntrySchemaZ.parse(entry)).not.toThrow();
48
- }
49
- });
50
-
51
- it("is deeply frozen so no surface can edit the shared table", () => {
52
- expect(Object.isFrozen(MULTIPLEXER_VERB_TABLE)).toBe(true);
53
- for (const entry of MULTIPLEXER_VERB_TABLE) {
54
- expect(Object.isFrozen(entry)).toBe(true);
55
- expect(Object.isFrozen(entry.execution)).toBe(true);
56
- expect(Object.isFrozen(entry.availabilityInputs)).toBe(true);
57
- }
58
- });
59
-
60
- it("has unique ids", () => {
61
- expect(new Set(MULTIPLEXER_VERB_IDS).size).toBe(MULTIPLEXER_VERB_IDS.length);
62
- });
63
-
64
- it("names only daemon actions that actually exist", () => {
65
- for (const entry of MULTIPLEXER_VERB_TABLE) {
66
- if (entry.execution.kind !== "daemon-action") continue;
67
- expect(Object.keys(ActionContractsZ)).toContain(entry.execution.action);
68
- }
69
- });
70
-
71
- it("names only AppWindow commands that actually exist", () => {
72
- const commands = AppWindowMutationCommandSchemaZ.options.map(
73
- (option) => option.shape.type.value,
74
- );
75
- for (const entry of MULTIPLEXER_VERB_TABLE) {
76
- if (entry.execution.kind !== "app-window") continue;
77
- expect(commands).toContain(entry.execution.command);
78
- }
79
- });
80
-
81
- it("marks exactly the verbs that destroy something as destructive", () => {
82
- const destructive = MULTIPLEXER_VERB_TABLE.filter((entry) => entry.destructive).map(
83
- (entry) => entry.id,
84
- );
85
- expect(destructive).toEqual(["window.link.unlink", "session.kill", "window.kill", "pane.kill"]);
86
- });
87
-
88
- it("leaves every tmux key hint unfilled until the keybinding bridge exists", () => {
89
- for (const entry of MULTIPLEXER_VERB_TABLE) {
90
- expect(entry.tmuxKeyHint).toBeNull();
91
- }
92
- });
93
-
94
- it("groups verbs by the object they act on", () => {
95
- expect(multiplexerVerbsForScope("pane").map((entry) => entry.id)).toEqual([
96
- "pane.split.right",
97
- "pane.split.down",
98
- "pane.kill",
99
- "pane.select",
100
- "pane.swap",
101
- "pane.resize",
102
- ]);
103
- });
104
-
105
- it("offers pane resize only where there is a border to move", () => {
106
- const resize = verb("pane.resize");
107
- expect(
108
- multiplexerVerbAvailability(resize, { workspaceConnected: true, windowPaneCount: 2 }),
109
- ).toEqual({ available: true });
110
- // A one-pane window has no border: tmux would grow nothing, so the rule is
111
- // stated up front rather than discovered by a drag that does nothing.
112
- expect(
113
- multiplexerVerbAvailability(resize, { workspaceConnected: true, windowPaneCount: 1 }),
114
- ).toMatchObject({ available: false });
115
- });
116
-
117
- it("offers pane swap only when another pane exists in the window", () => {
118
- const swap = verb("pane.swap");
119
- expect(
120
- multiplexerVerbAvailability(swap, { workspaceConnected: true, windowPaneCount: 2 }),
121
- ).toEqual({ available: true });
122
- expect(
123
- multiplexerVerbAvailability(swap, { workspaceConnected: true, windowPaneCount: 1 }),
124
- ).toMatchObject({ available: false });
125
- expect(swap.execution).toEqual({
126
- kind: "daemon-action",
127
- action: "workspace.pane.swap",
128
- });
129
- });
130
-
131
- it("recognises its own ids and rejects others", () => {
132
- expect(isMultiplexerVerbId("pane.kill")).toBe(true);
133
- expect(isMultiplexerVerbId("pane.obliterate")).toBe(false);
134
- expect(isMultiplexerVerbId(7)).toBe(false);
135
- expect(() => multiplexerVerb("pane.kill")).not.toThrow();
136
- });
137
-
138
- it("routes pane focus to tmux and stack activation to the layout document", () => {
139
- // The distinction gap 10 turns on: one of these reaches the multiplexer.
140
- expect(verb("pane.select").execution).toEqual({
141
- kind: "daemon-action",
142
- action: "workspace.pane.select",
143
- });
144
- expect(verb("stack.activate").execution).toEqual({
145
- kind: "app-window",
146
- command: "stack.activate",
147
- });
148
- });
149
- });
150
-
151
- describe("verb availability", () => {
152
- const connected = { workspaceConnected: true } as const;
153
-
154
- it("refuses a verb whose declared facts the surface did not gather", () => {
155
- const result = multiplexerVerbAvailability(verb("pane.kill"), connected);
156
- expect(result).toEqual({ available: false, reason: "windowPaneCount is unknown" });
157
- });
158
-
159
- it("offers nothing on a disconnected workspace", () => {
160
- const result = multiplexerVerbAvailability(verb("window.rename"), {
161
- workspaceConnected: false,
162
- });
163
- expect(result).toEqual({ available: false, reason: "the workspace is not connected" });
164
- });
165
-
166
- it("refuses to close a session's last window", () => {
167
- expect(
168
- multiplexerVerbAvailability(verb("window.kill"), { ...connected, sessionWindowCount: 1 }),
169
- ).toEqual({ available: false, reason: "this is the session's last window" });
170
- expect(
171
- multiplexerVerbAvailability(verb("window.kill"), { ...connected, sessionWindowCount: 2 }),
172
- ).toEqual({ available: true });
173
- });
174
-
175
- it("refuses to close a session's last pane but allows any other", () => {
176
- const facts = { ...connected, windowPaneCount: 1, sessionWindowCount: 1 };
177
- expect(multiplexerVerbAvailability(verb("pane.kill"), facts)).toEqual({
178
- available: false,
179
- reason: "this is the session's last pane",
180
- });
181
- // A split window's pane is closable, and so is a lone pane in a session
182
- // that still has another window to fall back to.
183
- expect(
184
- multiplexerVerbAvailability(verb("pane.kill"), { ...facts, windowPaneCount: 2 }),
185
- ).toEqual({ available: true });
186
- expect(
187
- multiplexerVerbAvailability(verb("pane.kill"), { ...facts, sessionWindowCount: 2 }),
188
- ).toEqual({ available: true });
189
- });
190
-
191
- it("offers zoom for a split window, and for unzooming whatever the pane count says", () => {
192
- expect(
193
- multiplexerVerbAvailability(verb("window.zoom.toggle"), {
194
- ...connected,
195
- windowPaneCount: 1,
196
- windowZoomed: false,
197
- }),
198
- ).toEqual({ available: false, reason: "this window has only one pane" });
199
- expect(
200
- multiplexerVerbAvailability(verb("window.zoom.toggle"), {
201
- ...connected,
202
- windowPaneCount: 2,
203
- windowZoomed: false,
204
- }),
205
- ).toEqual({ available: true });
206
- expect(
207
- multiplexerVerbAvailability(verb("window.zoom.toggle"), {
208
- ...connected,
209
- windowPaneCount: 1,
210
- windowZoomed: true,
211
- }),
212
- ).toEqual({ available: true });
213
- });
214
-
215
- it("does not offer focus on the pane that already has it", () => {
216
- expect(
217
- multiplexerVerbAvailability(verb("pane.select"), {
218
- ...connected,
219
- targetIsActivePane: true,
220
- }),
221
- ).toEqual({ available: false, reason: "this pane is already active" });
222
- expect(
223
- multiplexerVerbAvailability(verb("pane.select"), {
224
- ...connected,
225
- targetIsActivePane: false,
226
- }),
227
- ).toEqual({ available: true });
228
- });
229
-
230
- it("offers stack activation only inside a docked stack", () => {
231
- expect(
232
- multiplexerVerbAvailability(verb("stack.activate"), { targetIsDockedStackMember: true }),
233
- ).toEqual({ available: true });
234
- expect(
235
- multiplexerVerbAvailability(verb("stack.activate"), { targetIsDockedStackMember: false }),
236
- ).toEqual({ available: false, reason: "this window is not in a docked stack" });
237
- });
238
-
239
- it("offers a verb with no declared inputs unconditionally", () => {
240
- expect(multiplexerVerbAvailability(verb("session.new"), {})).toEqual({ available: true });
241
- });
242
- });
@@ -1,146 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import {
3
- resolvePaneAppearance,
4
- statusToneForDomainStatus,
5
- type PaneVisualStateV1,
6
- } from "../pane-appearance.ts";
7
-
8
- const baseState = (): PaneVisualStateV1 => ({
9
- structure: "docked",
10
- applicationFocus: { pane: false, terminalInput: false, windowActive: true },
11
- agentActivity: "idle",
12
- domainStatus: "idle",
13
- attention: "none",
14
- layoutInteraction: {
15
- editable: true,
16
- selected: false,
17
- dragging: false,
18
- resizing: false,
19
- previewing: false,
20
- },
21
- controlInteraction: {
22
- hover: false,
23
- focusVisible: false,
24
- pressed: false,
25
- disabled: false,
26
- loading: false,
27
- },
28
- });
29
-
30
- describe("pane appearance composition", () => {
31
- it("maps canonical domain statuses to stable tones", () => {
32
- expect(
33
- Object.fromEntries(
34
- (
35
- ["idle", "running", "blocked", "review", "done", "disconnected", "recovering"] as const
36
- ).map((status) => [status, statusToneForDomainStatus(status)]),
37
- ),
38
- ).toEqual({
39
- idle: "neutral",
40
- running: "info",
41
- blocked: "warning",
42
- review: "info",
43
- done: "success",
44
- disconnected: "danger",
45
- recovering: "danger",
46
- });
47
- });
48
-
49
- it("preserves focus, selection, attention, and action states in separate slots", () => {
50
- const state: PaneVisualStateV1 = {
51
- ...baseState(),
52
- structure: "floating",
53
- applicationFocus: { pane: true, terminalInput: true, windowActive: true },
54
- agentActivity: "running",
55
- domainStatus: "blocked",
56
- attention: "destructive",
57
- layoutInteraction: {
58
- editable: true,
59
- selected: true,
60
- dragging: true,
61
- resizing: false,
62
- previewing: true,
63
- },
64
- controlInteraction: {
65
- hover: true,
66
- focusVisible: true,
67
- pressed: true,
68
- disabled: true,
69
- loading: true,
70
- },
71
- };
72
- const appearance = resolvePaneAppearance(state);
73
-
74
- expect(appearance.header).toEqual(
75
- expect.objectContaining({ surface: "headerActive", focused: true, attention: "destructive" }),
76
- );
77
- expect(appearance.border).toEqual({
78
- role: "focused",
79
- strength: "decisive",
80
- ownsApplicationFocus: true,
81
- });
82
- expect(appearance.outerOutline).toEqual({
83
- visible: true,
84
- role: "selected",
85
- intent: "layout-selection",
86
- });
87
- expect(appearance.status).toEqual({
88
- domainStatus: "blocked",
89
- domainTone: "warning",
90
- attentionTone: "danger",
91
- tone: "danger",
92
- attention: "destructive",
93
- });
94
- expect(appearance.action).toEqual(
95
- expect.objectContaining({
96
- background: "disabled",
97
- focusOutline: "focused",
98
- hover: true,
99
- pressed: true,
100
- disabled: true,
101
- loading: true,
102
- interactive: false,
103
- }),
104
- );
105
- expect(appearance.accessibility).toEqual(
106
- expect.objectContaining({
107
- focused: true,
108
- terminalInputOwner: true,
109
- layoutSelected: true,
110
- hasAttention: true,
111
- busy: true,
112
- disabled: true,
113
- }),
114
- );
115
- });
116
-
117
- it("does not confuse terminal input ownership with application focus styling", () => {
118
- const state = baseState();
119
- state.applicationFocus = { pane: true, terminalInput: false, windowActive: true };
120
- const appFocused = resolvePaneAppearance(state);
121
- state.applicationFocus = { pane: true, terminalInput: true, windowActive: true };
122
- const terminalFocused = resolvePaneAppearance(state);
123
-
124
- expect(terminalFocused.border).toEqual(appFocused.border);
125
- expect(terminalFocused.header).toEqual(appFocused.header);
126
- expect(terminalFocused.accessibility.terminalInputOwner).toBe(true);
127
- });
128
-
129
- it("renders inactive-window focus quietly and remains pure", () => {
130
- const state = baseState();
131
- state.applicationFocus = { pane: true, terminalInput: true, windowActive: false };
132
- state.attention = "warning";
133
- const before = JSON.stringify(state);
134
- const first = resolvePaneAppearance(state);
135
- const second = resolvePaneAppearance(state);
136
-
137
- expect(first).toEqual(second);
138
- expect(JSON.stringify(state)).toBe(before);
139
- expect(first.header).toEqual(expect.objectContaining({ surface: "header", text: "muted" }));
140
- expect(first.border).toEqual({
141
- role: "attention",
142
- strength: "decisive",
143
- ownsApplicationFocus: false,
144
- });
145
- });
146
- });