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.
- package/README.md +1 -1
- package/bin/cli.js +2071 -625
- package/package.json +14 -5
- package/packages/contracts/src/desktop-host.ts +3 -0
- package/packages/contracts/src/saved-machines.ts +19 -0
- package/packages/contracts/src/terminal-replica.ts +1 -1
- package/packages/core/package.json +3 -2
- package/packages/core/src/terminal-delivery.ts +51 -3
- package/packages/core/src/terminal-fnv64-wasm.ts +4 -3
- package/packages/core/src/terminal-replica-hash-cache.ts +129 -31
- package/packages/core/src/terminal-replica-owned-row.ts +27 -0
- package/packages/core/src/terminal-replica.ts +13 -28
- package/packages/daemon/dist/command-center/daemon-fleet-facts-observer.js +96 -10
- package/packages/daemon/dist/command-center/resources/saved-machine-route.js +40 -1
- package/packages/daemon/dist/command-center/ws-events.js +5 -24
- package/packages/daemon/dist/lib/canonical-daemon-bootstrap.js +8 -0
- package/packages/daemon/dist/lib/canonical-daemon.js +28 -2
- package/packages/daemon/dist/lib/daemon-embed.js +1 -1
- package/packages/daemon/dist/lib/daemon-service-manager.js +122 -0
- package/packages/daemon/dist/lib/daemon-service-plan.js +127 -0
- package/packages/daemon/dist/lib/daemon-service.js +259 -0
- package/packages/daemon/dist/lib/install-origin.js +2 -0
- package/packages/daemon/dist/lib/local-fleet-request.js +9 -3
- package/packages/daemon/dist/lib/log.js +6 -10
- package/packages/daemon/dist/lib/managed-installer-update.js +67 -0
- package/packages/daemon/dist/lib/{tui-download-lock.js → private-operation-lock.js} +11 -11
- package/packages/daemon/dist/lib/remote-daemon-info.js +3 -2
- package/packages/daemon/dist/lib/remote-daemon-lifecycle.js +4 -4
- package/packages/daemon/dist/lib/remote-tmux-command.js +10 -0
- package/packages/daemon/dist/lib/runtime-namespace.js +28 -16
- package/packages/daemon/dist/lib/saved-machines.js +40 -2
- package/packages/daemon/dist/lib/ssh-daemon-transport.js +24 -9
- package/packages/daemon/dist/lib/tmux-server-owner.js +1 -1
- package/packages/daemon/dist/lib/tmux-server-registration.js +21 -3
- package/packages/daemon/dist/lib/tui-binary.js +2 -2
- package/packages/daemon/dist/lib/update.js +18 -0
- package/packages/daemon/dist/lib/workspace-multiplexer-verbs.js +24 -1
- package/packages/daemon/dist/machines.js +40 -4
- package/packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/Info.plist +2 -2
- package/packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/MacOS/tmux-ide-notifier +0 -0
- package/packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/Resources/Assets.car +0 -0
- package/packages/daemon/dist/native/TmuxIdeNotifier.app/Contents/_CodeSignature/CodeResources +2 -2
- package/packages/daemon/dist/terminal/attachments/direct-websocket.js +4 -1
- package/packages/daemon/dist/terminal/attachments/native-runtime.js +22 -13
- package/packages/daemon/dist/terminal/mirror/mirror-service.js +101 -3
- package/packages/daemon/dist/terminal/mirror/registered-window-guard.js +62 -0
- package/packages/daemon/dist/terminal/mirror/session-channel.js +75 -4
- package/packages/daemon/dist/terminal/mirror/shared-window-index.js +45 -0
- package/packages/daemon/dist/terminal/pane-stream/pane-stream-websocket.js +11 -1
- package/packages/daemon/dist/terminal/session-runtime/multiplexer-backend.js +1 -0
- package/packages/daemon/dist/terminal/session-runtime/registry.js +56 -7
- package/packages/daemon/dist/terminal/session-runtime/semantic-mutation-executor.js +3 -1
- package/packages/daemon/dist/tui/mirror/dialog-model.js +2 -35
- package/packages/daemon/dist/tui/mirror/runtime/application-daemon-authority-owner.js +8 -0
- package/packages/daemon/dist/tui/mirror/runtime/application-home-fleet.js +20 -2
- package/packages/daemon/dist/tui/mirror/runtime/application-machine-agents.js +7 -1
- package/packages/daemon/dist/tui/mirror/runtime/application-machine-authority.js +59 -9
- package/packages/daemon/dist/tui/mirror/runtime/application-machine-navigation.js +27 -19
- package/packages/daemon/dist/tui/mirror/runtime/application-machine-sidebar.jsx +23 -18
- package/packages/daemon/dist/tui/mirror/runtime/application-machine-startup.js +31 -2
- package/packages/daemon/dist/tui/mirror/runtime/application-palette-search-owner.js +7 -3
- package/packages/daemon/dist/tui/mirror/runtime/application-performance-log.js +3 -0
- package/packages/daemon/dist/tui/mirror/runtime/application-terminal-input-ingress.js +146 -2
- package/packages/daemon/dist/tui/mirror/runtime/application-terminal-interaction-controller.js +201 -50
- package/packages/daemon/dist/tui/mirror/runtime/bounded-performance-record-writer.js +50 -10
- package/packages/daemon/dist/tui/mirror/runtime/terminal-fast-lane-renderer-adapter.js +6 -5
- package/packages/daemon/dist/tui/mirror/runtime/terminal-pane-input-router.js +3 -0
- package/packages/daemon/dist/tui/mirror/runtime/workspace-terminal-fast-lane.js +8 -2
- package/packages/daemon/dist/tui/mirror/terminal-text.js +35 -0
- package/packages/daemon/dist/tui/mirror/workspace/connection-feedback.js +5 -3
- package/packages/daemon/src/command-center/daemon-fleet-facts-observer.ts +100 -10
- package/packages/daemon/src/command-center/resources/saved-machine-route.ts +48 -1
- package/packages/daemon/src/command-center/ws-events.ts +5 -25
- package/packages/daemon/src/lib/canonical-daemon-bootstrap.ts +12 -0
- package/packages/daemon/src/lib/canonical-daemon.ts +44 -2
- package/packages/daemon/src/lib/daemon-embed.ts +1 -0
- package/packages/daemon/src/lib/daemon-service-manager.ts +152 -0
- package/packages/daemon/src/lib/daemon-service-plan.ts +153 -0
- package/packages/daemon/src/lib/daemon-service.ts +301 -0
- package/packages/daemon/src/lib/install-origin.ts +5 -0
- package/packages/daemon/src/lib/local-fleet-request.ts +19 -3
- package/packages/daemon/src/lib/log.ts +13 -9
- package/packages/daemon/src/lib/managed-installer-update.ts +79 -0
- package/packages/daemon/src/lib/{tui-download-lock.ts → private-operation-lock.ts} +15 -11
- package/packages/daemon/src/lib/remote-daemon-info.ts +3 -3
- package/packages/daemon/src/lib/remote-daemon-lifecycle.ts +4 -4
- package/packages/daemon/src/lib/remote-tmux-command.ts +12 -0
- package/packages/daemon/src/lib/runtime-namespace.ts +27 -18
- package/packages/daemon/src/lib/saved-machines.ts +40 -1
- package/packages/daemon/src/lib/ssh-daemon-transport.ts +25 -7
- package/packages/daemon/src/lib/tmux-server-owner.ts +1 -0
- package/packages/daemon/src/lib/tmux-server-registration.ts +21 -3
- package/packages/daemon/src/lib/tui-binary.ts +2 -2
- package/packages/daemon/src/lib/update.ts +24 -0
- package/packages/daemon/src/lib/workspace-multiplexer-verbs.ts +22 -0
- package/packages/daemon/src/machines.ts +53 -5
- package/packages/daemon/src/terminal/attachments/direct-websocket.ts +8 -2
- package/packages/daemon/src/terminal/attachments/native-runtime.ts +28 -13
- package/packages/daemon/src/terminal/mirror/mirror-service.ts +105 -3
- package/packages/daemon/src/terminal/mirror/registered-window-guard.ts +66 -0
- package/packages/daemon/src/terminal/mirror/session-channel.ts +92 -4
- package/packages/daemon/src/terminal/mirror/shared-window-index.ts +42 -0
- package/packages/daemon/src/terminal/pane-stream/pane-stream-websocket.ts +12 -1
- package/packages/daemon/src/terminal/session-runtime/multiplexer-backend.ts +2 -0
- package/packages/daemon/src/terminal/session-runtime/registry.ts +70 -8
- package/packages/daemon/src/terminal/session-runtime/semantic-mutation-executor.ts +3 -1
- package/packages/daemon/src/tui/mirror/dialog-model.ts +2 -32
- package/packages/daemon/src/tui/mirror/runtime/application-daemon-authority-owner.ts +8 -0
- package/packages/daemon/src/tui/mirror/runtime/application-home-fleet.ts +19 -2
- package/packages/daemon/src/tui/mirror/runtime/application-machine-agents.ts +6 -1
- package/packages/daemon/src/tui/mirror/runtime/application-machine-authority.ts +60 -11
- package/packages/daemon/src/tui/mirror/runtime/application-machine-navigation.ts +39 -33
- package/packages/daemon/src/tui/mirror/runtime/application-machine-sidebar.tsx +31 -23
- package/packages/daemon/src/tui/mirror/runtime/application-machine-startup.ts +38 -2
- package/packages/daemon/src/tui/mirror/runtime/application-palette-search-owner.ts +7 -4
- package/packages/daemon/src/tui/mirror/runtime/application-performance-log.ts +3 -0
- package/packages/daemon/src/tui/mirror/runtime/application-root-v2.tsx +1 -1
- package/packages/daemon/src/tui/mirror/runtime/application-shell-view.tsx +47 -46
- package/packages/daemon/src/tui/mirror/runtime/application-terminal-input-ingress.ts +165 -2
- package/packages/daemon/src/tui/mirror/runtime/application-terminal-interaction-controller.ts +207 -53
- package/packages/daemon/src/tui/mirror/runtime/bounded-performance-record-writer.ts +49 -9
- package/packages/daemon/src/tui/mirror/runtime/terminal-fast-lane-renderer-adapter.ts +6 -5
- package/packages/daemon/src/tui/mirror/runtime/terminal-pane-input-router.ts +4 -0
- package/packages/daemon/src/tui/mirror/runtime/workspace-terminal-fast-lane.ts +8 -3
- package/packages/daemon/src/tui/mirror/terminal-text.ts +32 -0
- package/packages/daemon/src/tui/mirror/workspace/connection-feedback.ts +6 -3
- package/packages/daemon-client/src/fleet-connection-status.ts +10 -1
- package/packages/daemon-client/src/workspace-client.ts +4 -1
- package/packages/contracts/src/__tests__/actions-contract.test.ts +0 -119
- package/packages/contracts/src/__tests__/agent-graph-overlay.test.ts +0 -428
- package/packages/contracts/src/__tests__/app-window-mutation.test.ts +0 -51
- package/packages/contracts/src/__tests__/app-window-state.test.ts +0 -34
- package/packages/contracts/src/__tests__/application-shell.test.ts +0 -645
- package/packages/contracts/src/__tests__/automation-operations.test.ts +0 -78
- package/packages/contracts/src/__tests__/causal-cell.test.ts +0 -47
- package/packages/contracts/src/__tests__/client-view-state.test.ts +0 -115
- package/packages/contracts/src/__tests__/cohesion-fixture.test.ts +0 -106
- package/packages/contracts/src/__tests__/commands.test.ts +0 -86
- package/packages/contracts/src/__tests__/control.test.ts +0 -154
- package/packages/contracts/src/__tests__/daemon-events.test.ts +0 -405
- package/packages/contracts/src/__tests__/daemon-resources.test.ts +0 -143
- package/packages/contracts/src/__tests__/daemon-wire.test.ts +0 -149
- package/packages/contracts/src/__tests__/desktop-host.test.ts +0 -269
- package/packages/contracts/src/__tests__/desktop-missions.test.ts +0 -215
- package/packages/contracts/src/__tests__/experience-conformance.test.ts +0 -153
- package/packages/contracts/src/__tests__/experience-kernel-boundary.test.ts +0 -113
- package/packages/contracts/src/__tests__/experience-shell.test.ts +0 -65
- package/packages/contracts/src/__tests__/fixtures/daemon-wire-v2.json +0 -35
- package/packages/contracts/src/__tests__/fixtures/daemon-wire-v3.json +0 -35
- package/packages/contracts/src/__tests__/fixtures/daemon-wire-v4.json +0 -35
- package/packages/contracts/src/__tests__/fixtures/scoped-receipt.ts +0 -62
- package/packages/contracts/src/__tests__/fleet-agent-graph.test.ts +0 -231
- package/packages/contracts/src/__tests__/fleet-catalog.test.ts +0 -270
- package/packages/contracts/src/__tests__/fleet-lifecycle.test.ts +0 -62
- package/packages/contracts/src/__tests__/focus-overlay.test.ts +0 -110
- package/packages/contracts/src/__tests__/ide-config.test.ts +0 -64
- package/packages/contracts/src/__tests__/interaction-evidence.test.ts +0 -288
- package/packages/contracts/src/__tests__/interaction-receipt-v2.test.ts +0 -72
- package/packages/contracts/src/__tests__/issue-error.test.ts +0 -78
- package/packages/contracts/src/__tests__/mission-projections.test.ts +0 -186
- package/packages/contracts/src/__tests__/missions.test.ts +0 -272
- package/packages/contracts/src/__tests__/multiplexer-verbs.test.ts +0 -242
- package/packages/contracts/src/__tests__/pane-appearance.test.ts +0 -146
- package/packages/contracts/src/__tests__/pane-read-result.test.ts +0 -55
- package/packages/contracts/src/__tests__/pane-stream.test.ts +0 -536
- package/packages/contracts/src/__tests__/pane-widget-marker.test.ts +0 -327
- package/packages/contracts/src/__tests__/performance-metrics.test.ts +0 -73
- package/packages/contracts/src/__tests__/performance-qualification.test.ts +0 -137
- package/packages/contracts/src/__tests__/rich-card-widget.test.ts +0 -29
- package/packages/contracts/src/__tests__/session-runtime.test.ts +0 -512
- package/packages/contracts/src/__tests__/startup-readiness.test.ts +0 -409
- package/packages/contracts/src/__tests__/terminal-attachment-stream.test.ts +0 -72
- package/packages/contracts/src/__tests__/terminal-attachments.test.ts +0 -329
- package/packages/contracts/src/__tests__/terminal-delivery.test.ts +0 -88
- package/packages/contracts/src/__tests__/terminal-runtime-inventory.test.ts +0 -68
- package/packages/contracts/src/__tests__/terminals.test.ts +0 -87
- package/packages/contracts/src/__tests__/tmux-server-scope.test.ts +0 -166
- package/packages/contracts/src/__tests__/transport-contract-loading.test.ts +0 -91
- package/packages/contracts/src/__tests__/visual-tokens.test.ts +0 -224
- package/packages/contracts/src/__tests__/window-links.test.ts +0 -243
- package/packages/contracts/src/__tests__/workspace-changes-resource.test.ts +0 -317
- package/packages/contracts/src/__tests__/workspace-changes-view.test.ts +0 -122
- package/packages/contracts/src/__tests__/workspace-config.test.ts +0 -294
- package/packages/contracts/src/__tests__/workspace-files-resource.test.ts +0 -261
- package/packages/contracts/src/__tests__/workspace-files-tree.test.ts +0 -147
- package/packages/contracts/src/__tests__/workspace-pane-creation.test.ts +0 -249
- package/packages/contracts/src/__tests__/workspace-promotion.test.ts +0 -94
- package/packages/contracts/src/__tests__/workspace-resource-identity.test.ts +0 -90
- package/packages/contracts/src/daemon-resource-request.test.ts +0 -192
- package/packages/contracts/src/native-operation-identity.test.ts +0 -23
- package/packages/contracts/src/workspace-admission.test.ts +0 -21
- package/packages/contracts/src/workspace-catalog-resource.test.ts +0 -146
- package/packages/core/src/agent-provisioning.test.ts +0 -42
- package/packages/core/src/application-shell-session.test.ts +0 -105
- package/packages/core/src/interaction-evidence.test.ts +0 -134
- package/packages/core/src/interaction-flow.test.ts +0 -66
- package/packages/core/src/interaction-receipts.test.ts +0 -671
- package/packages/core/src/navigator.test.ts +0 -34
- package/packages/core/src/optimistic-projection-conformance.test.ts +0 -75
- package/packages/core/src/optimistic-projection.test.ts +0 -118
- package/packages/core/src/performance-metrics.test.ts +0 -121
- package/packages/core/src/performance-qualification.test.ts +0 -283
- package/packages/core/src/saved-machines.test.ts +0 -80
- package/packages/core/src/terminal-compact-cold.test.ts +0 -87
- package/packages/core/src/terminal-conformance.test.ts +0 -48
- package/packages/core/src/terminal-delivery-cache-lifetime.test.ts +0 -167
- package/packages/core/src/terminal-delivery-encode-cooperative.test.ts +0 -140
- package/packages/core/src/terminal-delivery-representation-hash.test.ts +0 -77
- package/packages/core/src/terminal-delivery.test.ts +0 -1471
- package/packages/core/src/terminal-fnv64-wasm.test.ts +0 -61
- package/packages/core/src/terminal-replica-cold.test.ts +0 -31
- package/packages/core/src/terminal-replica-cooperative.test.ts +0 -170
- package/packages/core/src/terminal-replica-hash-cache.test.ts +0 -283
- package/packages/core/src/terminal-replica.test.ts +0 -347
- package/packages/core/src/workspace-selection.test.ts +0 -63
- package/packages/daemon/dist/__tests__/support.js +0 -33
- package/packages/daemon/dist/lib/__tests__/fixtures/workspace-state-writer.js +0 -58
- package/packages/daemon/dist/lib/__tests__/installed-recovery-fixture.js +0 -400
- package/packages/daemon/dist/terminal/__tests__/MockPtyAdapter.js +0 -182
- package/packages/daemon/dist/terminal/mirror/__tests__/scripted-channel.js +0 -98
- package/packages/daemon/dist/terminal/mirror/__tests__/simulated-channel.js +0 -156
- package/packages/daemon/src/tui/mirror/__snapshots__/activity-surface-renderer.test.tsx.snap +0 -42
- package/packages/daemon/src/tui/mirror/__snapshots__/changes-terminal-surface-renderer.test.tsx.snap +0 -267
- package/packages/daemon/src/tui/mirror/__snapshots__/home-files-surface-renderer.test.tsx.snap +0 -267
- package/packages/daemon/src/tui/mirror/__snapshots__/missions-surface-renderer.test.tsx.snap +0 -134
- package/packages/daemon/src/tui/mirror/__snapshots__/recipes-gallery-renderer.test.tsx.snap +0 -141
- package/packages/daemon/src/tui/mirror/__snapshots__/shell-chrome-renderer.test.tsx.snap +0 -134
- package/packages/daemon/src/tui/mirror/runtime/__snapshots__/application-shell-view-renderer.test.tsx.snap +0 -87
- package/packages/daemon/src/tui/mirror/workspace/__snapshots__/agent-terminal-canvas-renderer.test.tsx.snap +0 -348
- package/packages/daemon/src/tui/mirror/workspace/__snapshots__/application-shell-renderer.test.tsx.snap +0 -134
- package/packages/daemon/src/tui/mirror/workspace/__snapshots__/command-palette-surface-renderer.test.tsx.snap +0 -255
- package/packages/daemon/src/tui/mirror/workspace/__snapshots__/pane-frame-renderer.test.tsx.snap +0 -525
- package/packages/daemon/src/tui/mirror/workspace/__snapshots__/terminal-pane-header-polish-renderer.test.tsx.snap +0 -31
- package/packages/daemon/src/tui/mirror/workspace/__snapshots__/workbench-shell-renderer.test.tsx.snap +0 -134
- package/packages/daemon-client/src/application-shell-session.test.ts +0 -196
- package/packages/daemon-client/src/automation-client.test.ts +0 -214
- package/packages/daemon-client/src/bootstrap-coordinator.test.ts +0 -145
- package/packages/daemon-client/src/connection-supervisor.test.ts +0 -109
- package/packages/daemon-client/src/direct-application-shell-transport.test.ts +0 -941
- package/packages/daemon-client/src/first-latest-coordinator.test.ts +0 -175
- package/packages/daemon-client/src/fleet-dial-scheduler.test.ts +0 -114
- package/packages/daemon-client/src/fleet-environments.test.ts +0 -40
- package/packages/daemon-client/src/generation-bound-store-timers.test.ts +0 -74
- package/packages/daemon-client/src/owner-action-client.test.ts +0 -245
- package/packages/daemon-client/src/pane-stream-client.test.ts +0 -2841
- package/packages/daemon-client/src/pane-stream-clock-calibration.test.ts +0 -207
- package/packages/daemon-client/src/pane-stream-loopback-benchmark.test.ts +0 -51
- package/packages/daemon-client/src/push-resource-session.test.ts +0 -509
- package/packages/daemon-client/src/resource-replica.test.ts +0 -186
- package/packages/daemon-client/src/runtime-resource-ledger.test.ts +0 -18
- package/packages/daemon-client/src/scoped-tmux-server-transport.test.ts +0 -114
- package/packages/daemon-client/src/terminal-fast-lane.test.ts +0 -835
- package/packages/daemon-client/src/tmux-server-client.test.ts +0 -279
- package/packages/daemon-client/src/tmux-server-interaction-events.test.ts +0 -230
- package/packages/daemon-client/src/workspace-catalog-v2.test.ts +0 -109
- package/packages/daemon-client/src/workspace-client-boundaries.test.ts +0 -59
- package/packages/daemon-client/src/workspace-client-operations.test.ts +0 -96
- package/packages/daemon-client/src/workspace-client.test.ts +0 -2912
- package/packages/daemon-client/src/workspace-event-supervisor.test.ts +0 -1086
- package/packages/daemon-client/src/workspace-pane-client.test.ts +0 -80
- package/packages/presentation/src/presentation-contract.test.ts +0 -63
- package/packages/tmux-bridge/src/runner.test.ts +0 -614
- package/packages/tmux-bridge/src/targeting.test.ts +0 -107
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import {
|
|
3
|
-
AutomationExecuteRequestSchemaZ,
|
|
4
|
-
AutomationOperationStatusSchemaZ,
|
|
5
|
-
AutomationReserveRequestSchemaZ,
|
|
6
|
-
} from "../automation-operations.ts";
|
|
7
|
-
|
|
8
|
-
const id = "00000000-0000-4000-8000-000000000001";
|
|
9
|
-
const target = {
|
|
10
|
-
kind: "pane",
|
|
11
|
-
environmentId: id,
|
|
12
|
-
serverScope: { serverId: `tmux-server.${"a".repeat(32)}`, generation: id },
|
|
13
|
-
paneLifetimeId: id,
|
|
14
|
-
workspaceName: "workspace.project",
|
|
15
|
-
semanticPaneId: "pane.editor",
|
|
16
|
-
};
|
|
17
|
-
const request = {
|
|
18
|
-
version: 1,
|
|
19
|
-
intent: { kind: "send", target, source: null, text: "hello", enter: true },
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
describe("automation boundary", () => {
|
|
23
|
-
it("requires resolved lifetime and explicit source absence", () => {
|
|
24
|
-
expect(AutomationReserveRequestSchemaZ.safeParse(request).success).toBe(true);
|
|
25
|
-
for (const changed of [
|
|
26
|
-
{ ...request.intent, target: { ...target, paneLifetimeId: undefined } },
|
|
27
|
-
{ ...request.intent, source: undefined },
|
|
28
|
-
{ ...request.intent, target: { ...target, runtimePaneId: "%0" } },
|
|
29
|
-
{ ...request.intent, origin: "tui" },
|
|
30
|
-
{ ...request.intent, credential: "secret" },
|
|
31
|
-
])
|
|
32
|
-
expect(
|
|
33
|
-
AutomationReserveRequestSchemaZ.safeParse({ ...request, intent: changed }).success,
|
|
34
|
-
).toBe(false);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it("bounds UTF-8 bytes and excludes NUL rather than counting only JS characters", () => {
|
|
38
|
-
const parse = (text: string) =>
|
|
39
|
-
AutomationReserveRequestSchemaZ.safeParse({ ...request, intent: { ...request.intent, text } })
|
|
40
|
-
.success;
|
|
41
|
-
expect(parse("a".repeat(16384))).toBe(true);
|
|
42
|
-
expect(parse("a".repeat(16385))).toBe(false);
|
|
43
|
-
expect(parse("🙂".repeat(4096))).toBe(true);
|
|
44
|
-
expect(parse("🙂".repeat(4097))).toBe(false);
|
|
45
|
-
expect(parse("a\0b")).toBe(false);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it("requires a generation-fenced execution handle", () => {
|
|
49
|
-
expect(AutomationExecuteRequestSchemaZ.safeParse(request).success).toBe(false);
|
|
50
|
-
expect(
|
|
51
|
-
AutomationExecuteRequestSchemaZ.safeParse({
|
|
52
|
-
...request,
|
|
53
|
-
handle: { generation: id, operationId: id },
|
|
54
|
-
}).success,
|
|
55
|
-
).toBe(true);
|
|
56
|
-
expect(
|
|
57
|
-
AutomationExecuteRequestSchemaZ.safeParse({ ...request, handle: { operationId: id } })
|
|
58
|
-
.success,
|
|
59
|
-
).toBe(false);
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it("never admits sent or captured content to operation status", () => {
|
|
63
|
-
expect(
|
|
64
|
-
AutomationOperationStatusSchemaZ.safeParse({
|
|
65
|
-
status: "completed",
|
|
66
|
-
result: { kind: "read", capturedBytes: 12, returnedBytes: 12, truncated: false },
|
|
67
|
-
}).success,
|
|
68
|
-
).toBe(true);
|
|
69
|
-
for (const key of ["text", "content", "snapshot", "credential"]) {
|
|
70
|
-
expect(
|
|
71
|
-
AutomationOperationStatusSchemaZ.safeParse({
|
|
72
|
-
status: "completed",
|
|
73
|
-
result: { kind: "send", submitted: true, [key]: "private" },
|
|
74
|
-
}).success,
|
|
75
|
-
).toBe(false);
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
});
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { CausalCellProbeV1SchemaZ } from "../causal-cell.ts";
|
|
3
|
-
import { TerminalReplicaCellSchemaZ } from "../terminal-replica.ts";
|
|
4
|
-
|
|
5
|
-
const cell = TerminalReplicaCellSchemaZ.parse({
|
|
6
|
-
grapheme: " ",
|
|
7
|
-
width: 1,
|
|
8
|
-
foreground: { kind: "default" },
|
|
9
|
-
background: { kind: "default" },
|
|
10
|
-
attributes: 0,
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
function probe() {
|
|
14
|
-
return {
|
|
15
|
-
version: 1,
|
|
16
|
-
capability: "causal-cell-v1",
|
|
17
|
-
traceId: "00000000-0000-4000-8000-000000000099",
|
|
18
|
-
clientId: "client:test",
|
|
19
|
-
transportNonce: "00000000-0000-4000-8000-000000000010",
|
|
20
|
-
deliveryNonce: "00000000-0000-4000-8000-000000000011",
|
|
21
|
-
inputSequence: 1,
|
|
22
|
-
semanticPaneId: "pane.alpha",
|
|
23
|
-
generation: "11111111-1111-4111-8111-111111111111",
|
|
24
|
-
incarnation: "one",
|
|
25
|
-
baselineRevision: 7,
|
|
26
|
-
baselineStateHash: "0000000000000000",
|
|
27
|
-
geometry: { cols: 2, rows: 1, row: 0, column: 1 },
|
|
28
|
-
before: cell,
|
|
29
|
-
after: { ...cell, grapheme: "X" },
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
describe("causal-cell-v1 contracts", () => {
|
|
34
|
-
it("accepts an exact width-1 probe", () => {
|
|
35
|
-
expect(CausalCellProbeV1SchemaZ.safeParse(probe()).success).toBe(true);
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it.each([0, 2])("rejects non-canonical width %s before/after cells", (width) => {
|
|
39
|
-
expect(
|
|
40
|
-
CausalCellProbeV1SchemaZ.safeParse({ ...probe(), before: { ...cell, width } }).success,
|
|
41
|
-
).toBe(false);
|
|
42
|
-
expect(
|
|
43
|
-
CausalCellProbeV1SchemaZ.safeParse({ ...probe(), after: { ...cell, grapheme: "X", width } })
|
|
44
|
-
.success,
|
|
45
|
-
).toBe(false);
|
|
46
|
-
});
|
|
47
|
-
});
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
|
|
3
|
-
import { AppWindowDocumentV1SchemaZ } from "../app-window-state.ts";
|
|
4
|
-
import {
|
|
5
|
-
ClientViewStateV1SchemaZ,
|
|
6
|
-
createClientViewStateV1,
|
|
7
|
-
reconcileClientViewStateV1,
|
|
8
|
-
} from "../client-view-state.ts";
|
|
9
|
-
|
|
10
|
-
const shared = AppWindowDocumentV1SchemaZ.parse({
|
|
11
|
-
version: 1,
|
|
12
|
-
revision: 4,
|
|
13
|
-
updatedAt: "2026-08-07T08:00:00.000Z",
|
|
14
|
-
windows: {
|
|
15
|
-
"window.one": {
|
|
16
|
-
id: "window.one",
|
|
17
|
-
source: { kind: "terminal", terminalSourceId: "pane.one" },
|
|
18
|
-
title: "One",
|
|
19
|
-
placement: { mode: "docked", docked: { stackId: "stack.main", index: 0 }, floating: null },
|
|
20
|
-
},
|
|
21
|
-
"window.two": {
|
|
22
|
-
id: "window.two",
|
|
23
|
-
source: { kind: "terminal", terminalSourceId: "pane.two" },
|
|
24
|
-
title: "Two",
|
|
25
|
-
placement: { mode: "docked", docked: { stackId: "stack.main", index: 1 }, floating: null },
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
dockRoot: {
|
|
29
|
-
type: "stack",
|
|
30
|
-
id: "stack.main",
|
|
31
|
-
windowIds: ["window.one", "window.two"],
|
|
32
|
-
activeWindowId: "window.one",
|
|
33
|
-
},
|
|
34
|
-
dockState: { mode: "open", preferredHeight: 320, focusZone: "canvas" },
|
|
35
|
-
floatingOrder: [],
|
|
36
|
-
focusedWindowId: "window.one",
|
|
37
|
-
activeLayoutId: null,
|
|
38
|
-
layouts: {},
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
describe("ClientViewStateV1", () => {
|
|
42
|
-
it("lets two views retain different presentation over one shared layout", () => {
|
|
43
|
-
const first = ClientViewStateV1SchemaZ.parse({
|
|
44
|
-
...createClientViewStateV1({
|
|
45
|
-
clientId: "client.browser",
|
|
46
|
-
viewId: "view.first",
|
|
47
|
-
workspaceId: "workspace.shared",
|
|
48
|
-
legacyDocument: shared,
|
|
49
|
-
}),
|
|
50
|
-
focusedWindowId: "window.one",
|
|
51
|
-
selectedWindowIds: ["window.one"],
|
|
52
|
-
activeWindowIdsByStack: { "stack.main": "window.one" },
|
|
53
|
-
dock: {
|
|
54
|
-
mode: "open",
|
|
55
|
-
preferredHeight: 320,
|
|
56
|
-
focusZone: "dock-body",
|
|
57
|
-
activeTabId: "changes",
|
|
58
|
-
},
|
|
59
|
-
viewport: { x: -100, y: 20, scale: 1.25 },
|
|
60
|
-
});
|
|
61
|
-
const second = ClientViewStateV1SchemaZ.parse({
|
|
62
|
-
...first,
|
|
63
|
-
viewId: "view.second",
|
|
64
|
-
focusedWindowId: "window.two",
|
|
65
|
-
selectedWindowIds: ["window.two"],
|
|
66
|
-
activeWindowIdsByStack: { "stack.main": "window.two" },
|
|
67
|
-
dock: {
|
|
68
|
-
mode: "collapsed",
|
|
69
|
-
preferredHeight: 180,
|
|
70
|
-
focusZone: "canvas",
|
|
71
|
-
activeTabId: "activity",
|
|
72
|
-
},
|
|
73
|
-
viewport: { x: 40, y: -60, scale: 0.8 },
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
expect(first.focusedWindowId).toBe("window.one");
|
|
77
|
-
expect(second.focusedWindowId).toBe("window.two");
|
|
78
|
-
expect(first.dock).not.toEqual(second.dock);
|
|
79
|
-
expect(first.viewport).not.toEqual(second.viewport);
|
|
80
|
-
expect(shared.focusedWindowId).toBe("window.one");
|
|
81
|
-
expect(shared.dockRoot?.type === "stack" && shared.dockRoot.activeWindowId).toBe("window.one");
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
it("drops stale shared-layout references while retaining local presentation", () => {
|
|
85
|
-
const state = ClientViewStateV1SchemaZ.parse({
|
|
86
|
-
...createClientViewStateV1({
|
|
87
|
-
clientId: "client.browser",
|
|
88
|
-
viewId: "view.first",
|
|
89
|
-
workspaceId: "workspace.shared",
|
|
90
|
-
legacyDocument: shared,
|
|
91
|
-
}),
|
|
92
|
-
focusedWindowId: "window.two",
|
|
93
|
-
selectedWindowIds: ["window.two"],
|
|
94
|
-
activeWindowIdsByStack: { "stack.main": "window.two" },
|
|
95
|
-
viewport: { x: 10, y: 20, scale: 1.5 },
|
|
96
|
-
});
|
|
97
|
-
const oneOnly = AppWindowDocumentV1SchemaZ.parse({
|
|
98
|
-
...shared,
|
|
99
|
-
windows: { "window.one": shared.windows["window.one"] },
|
|
100
|
-
dockRoot: {
|
|
101
|
-
type: "stack",
|
|
102
|
-
id: "stack.main",
|
|
103
|
-
windowIds: ["window.one"],
|
|
104
|
-
activeWindowId: "window.one",
|
|
105
|
-
},
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
const reconciled = reconcileClientViewStateV1(state, oneOnly);
|
|
109
|
-
|
|
110
|
-
expect(reconciled.focusedWindowId).toBeNull();
|
|
111
|
-
expect(reconciled.selectedWindowIds).toEqual([]);
|
|
112
|
-
expect(reconciled.activeWindowIdsByStack).toEqual({});
|
|
113
|
-
expect(reconciled.viewport).toEqual({ x: 10, y: 20, scale: 1.5 });
|
|
114
|
-
});
|
|
115
|
-
});
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { COHESION_FIXTURE_V1, CohesionFixtureV1SchemaZ } from "../cohesion-fixture.ts";
|
|
3
|
-
import { resolvePaneAppearance } from "../pane-appearance.ts";
|
|
4
|
-
import { resolveSemanticInputLayer } from "../focus-overlay.ts";
|
|
5
|
-
import { resolveVisualTheme } from "../visual-tokens.ts";
|
|
6
|
-
|
|
7
|
-
describe("CohesionFixtureV1", () => {
|
|
8
|
-
it("round-trips as strict serialized cross-host acceptance input", () => {
|
|
9
|
-
expect(CohesionFixtureV1SchemaZ.parse(JSON.parse(JSON.stringify(COHESION_FIXTURE_V1)))).toEqual(
|
|
10
|
-
COHESION_FIXTURE_V1,
|
|
11
|
-
);
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
it("exercises every dock tool and orthogonal composed pane states", () => {
|
|
15
|
-
expect(COHESION_FIXTURE_V1.dock.tools.map(({ id }) => id)).toEqual([
|
|
16
|
-
"files",
|
|
17
|
-
"changes",
|
|
18
|
-
"missions",
|
|
19
|
-
"activity",
|
|
20
|
-
]);
|
|
21
|
-
const appearances = COHESION_FIXTURE_V1.panes.map(({ state }) => resolvePaneAppearance(state));
|
|
22
|
-
expect(appearances).toEqual(
|
|
23
|
-
expect.arrayContaining([
|
|
24
|
-
expect.objectContaining({
|
|
25
|
-
border: expect.objectContaining({ role: "focused" }),
|
|
26
|
-
status: expect.objectContaining({ attentionTone: "info" }),
|
|
27
|
-
}),
|
|
28
|
-
expect.objectContaining({
|
|
29
|
-
outerOutline: expect.objectContaining({ role: "selected" }),
|
|
30
|
-
}),
|
|
31
|
-
expect.objectContaining({
|
|
32
|
-
status: expect.objectContaining({ domainStatus: "recovering", tone: "danger" }),
|
|
33
|
-
action: expect.objectContaining({ disabled: true, loading: true }),
|
|
34
|
-
}),
|
|
35
|
-
]),
|
|
36
|
-
);
|
|
37
|
-
expect(resolveSemanticInputLayer(COHESION_FIXTURE_V1.focus)).toEqual({
|
|
38
|
-
kind: "command-palette",
|
|
39
|
-
overlayId: "overlay.palette",
|
|
40
|
-
});
|
|
41
|
-
expect(
|
|
42
|
-
resolveVisualTheme({
|
|
43
|
-
userTheme: COHESION_FIXTURE_V1.theme.user,
|
|
44
|
-
projectTheme: COHESION_FIXTURE_V1.theme.project ?? undefined,
|
|
45
|
-
accessibility: COHESION_FIXTURE_V1.theme.accessibility,
|
|
46
|
-
}).appearance,
|
|
47
|
-
).toBe("dark");
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it("rejects broken cross-field identity and state ownership", () => {
|
|
51
|
-
const copy = JSON.parse(JSON.stringify(COHESION_FIXTURE_V1)) as Record<string, unknown>;
|
|
52
|
-
const focus = copy.focus as Record<string, unknown>;
|
|
53
|
-
focus.appFocusedPaneId = "pane.unknown";
|
|
54
|
-
expect(CohesionFixtureV1SchemaZ.safeParse(copy).success).toBe(false);
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it("contains no renderer geometry or live transport handles", () => {
|
|
58
|
-
const forbiddenKeys = new Set([
|
|
59
|
-
"x",
|
|
60
|
-
"y",
|
|
61
|
-
"width",
|
|
62
|
-
"height",
|
|
63
|
-
"rect",
|
|
64
|
-
"bounds",
|
|
65
|
-
"tmuxPaneId",
|
|
66
|
-
"ptyId",
|
|
67
|
-
"xtermId",
|
|
68
|
-
"electronWindowId",
|
|
69
|
-
"nativeHandle",
|
|
70
|
-
]);
|
|
71
|
-
const forbiddenUnits = new Set(["px", "rem", "em", "cell", "row", "column"]);
|
|
72
|
-
const findings: string[] = [];
|
|
73
|
-
const walk = (value: unknown, path = "fixture"): void => {
|
|
74
|
-
if (Array.isArray(value))
|
|
75
|
-
return value.forEach((child, index) => walk(child, `${path}.${index}`));
|
|
76
|
-
if (!value || typeof value !== "object") return;
|
|
77
|
-
for (const [key, child] of Object.entries(value)) {
|
|
78
|
-
if (forbiddenKeys.has(key)) findings.push(`${path}.${key}`);
|
|
79
|
-
if (key === "unit" && typeof child === "string" && forbiddenUnits.has(child)) {
|
|
80
|
-
findings.push(`${path}.${key}:${child}`);
|
|
81
|
-
}
|
|
82
|
-
walk(child, `${path}.${key}`);
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
walk(COHESION_FIXTURE_V1);
|
|
86
|
-
expect(findings).toEqual([]);
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
it("is deeply frozen so adapters cannot decorate shared input with host measurements", () => {
|
|
90
|
-
const mutableObjects: string[] = [];
|
|
91
|
-
const walk = (value: unknown, path = "fixture"): void => {
|
|
92
|
-
if (!value || typeof value !== "object") return;
|
|
93
|
-
if (!Object.isFrozen(value)) mutableObjects.push(path);
|
|
94
|
-
if (Array.isArray(value)) {
|
|
95
|
-
value.forEach((child, index) => walk(child, `${path}.${index}`));
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
for (const [key, child] of Object.entries(value)) walk(child, `${path}.${key}`);
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
walk(COHESION_FIXTURE_V1);
|
|
102
|
-
expect(mutableObjects).toEqual([]);
|
|
103
|
-
expect(Reflect.set(COHESION_FIXTURE_V1.project, "name", "host-decorated")).toBe(false);
|
|
104
|
-
expect(COHESION_FIXTURE_V1.project.name).toBe("tmux-ide");
|
|
105
|
-
});
|
|
106
|
-
});
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import {
|
|
3
|
-
APPLICATION_SHELL_COMMAND_IDS,
|
|
4
|
-
COMMAND_PROTOCOL_VERSION,
|
|
5
|
-
CommandAvailabilitySchemaZ,
|
|
6
|
-
CommandDescriptorSchemaZ,
|
|
7
|
-
CommandInvocationSchemaZ,
|
|
8
|
-
WORKSPACE_WINDOW_MODE_COMMAND_IDS,
|
|
9
|
-
type CommandDescriptor,
|
|
10
|
-
type CommandInvocation,
|
|
11
|
-
} from "../commands.ts";
|
|
12
|
-
|
|
13
|
-
const descriptor: CommandDescriptor = {
|
|
14
|
-
version: COMMAND_PROTOCOL_VERSION,
|
|
15
|
-
id: "workspace.view.activate",
|
|
16
|
-
owner: "renderer",
|
|
17
|
-
label: "Activate view",
|
|
18
|
-
category: "workspace",
|
|
19
|
-
schemas: { input: "workspace.view.activate.input.v1" },
|
|
20
|
-
dangerous: false,
|
|
21
|
-
confirmation: "none",
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
const invocation: CommandInvocation = {
|
|
25
|
-
version: COMMAND_PROTOCOL_VERSION,
|
|
26
|
-
id: descriptor.id,
|
|
27
|
-
source: { kind: "keyboard", surface: "workbench" },
|
|
28
|
-
args: { viewId: "terminals", nested: { selected: true }, rows: [1, 2] },
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
describe("command protocol", () => {
|
|
32
|
-
it("round-trips serializable descriptors and invocations", () => {
|
|
33
|
-
expect(CommandDescriptorSchemaZ.parse(JSON.parse(JSON.stringify(descriptor)))).toEqual(
|
|
34
|
-
descriptor,
|
|
35
|
-
);
|
|
36
|
-
expect(CommandInvocationSchemaZ.parse(JSON.parse(JSON.stringify(invocation)))).toEqual(
|
|
37
|
-
invocation,
|
|
38
|
-
);
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it("rejects non-namespaced ids and non-JSON arguments", () => {
|
|
42
|
-
expect(CommandDescriptorSchemaZ.safeParse({ ...descriptor, id: "quit" }).success).toBe(false);
|
|
43
|
-
expect(
|
|
44
|
-
CommandInvocationSchemaZ.safeParse({
|
|
45
|
-
...invocation,
|
|
46
|
-
args: { callback: () => undefined },
|
|
47
|
-
}).success,
|
|
48
|
-
).toBe(false);
|
|
49
|
-
expect(
|
|
50
|
-
CommandInvocationSchemaZ.safeParse({
|
|
51
|
-
...invocation,
|
|
52
|
-
args: { count: Number.NaN },
|
|
53
|
-
}).success,
|
|
54
|
-
).toBe(false);
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it("keeps availability outcomes serializable and explicit", () => {
|
|
58
|
-
expect(CommandAvailabilitySchemaZ.parse({ available: true })).toEqual({ available: true });
|
|
59
|
-
expect(
|
|
60
|
-
CommandAvailabilitySchemaZ.parse({ available: false, reason: "no active view" }),
|
|
61
|
-
).toEqual({ available: false, reason: "no active view" });
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it("reserves valid window-mode ids without registering behavior", () => {
|
|
65
|
-
expect(WORKSPACE_WINDOW_MODE_COMMAND_IDS).toEqual([
|
|
66
|
-
"workspace.windowMode.enter",
|
|
67
|
-
"workspace.windowMode.exit",
|
|
68
|
-
"workspace.windowMode.cancel",
|
|
69
|
-
"workspace.windowMode.focus",
|
|
70
|
-
"workspace.windowMode.move",
|
|
71
|
-
"workspace.windowMode.resize",
|
|
72
|
-
"workspace.windowMode.float.toggle",
|
|
73
|
-
"workspace.windowMode.maximize.toggle",
|
|
74
|
-
"workspace.windowMode.close",
|
|
75
|
-
]);
|
|
76
|
-
for (const id of WORKSPACE_WINDOW_MODE_COMMAND_IDS) {
|
|
77
|
-
expect(CommandDescriptorSchemaZ.safeParse({ ...descriptor, id }).success).toBe(true);
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
it("keeps application-shell ids immutable and isolated from live renderer ids", () => {
|
|
82
|
-
expect(Object.isFrozen(APPLICATION_SHELL_COMMAND_IDS)).toBe(true);
|
|
83
|
-
expect(Object.values(APPLICATION_SHELL_COMMAND_IDS)).not.toContain("app.palette.open");
|
|
84
|
-
expect(Object.values(APPLICATION_SHELL_COMMAND_IDS)).not.toContain("workspace.dock.activate");
|
|
85
|
-
});
|
|
86
|
-
});
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Schema tests for the control-socket protocol (M23.3): the versioned
|
|
3
|
-
* envelope and the per-verb params. These pin the WIRE contract — a change
|
|
4
|
-
* that breaks one of these breaks every connected agent loop.
|
|
5
|
-
*/
|
|
6
|
-
import { describe, expect, it } from "vitest";
|
|
7
|
-
import {
|
|
8
|
-
CONTROL_PROTOCOL_VERSION,
|
|
9
|
-
CONTROL_WAIT_MAX_TIMEOUT_MS,
|
|
10
|
-
agentStatusEventSchema,
|
|
11
|
-
controlEventSchema,
|
|
12
|
-
controlRequestSchema,
|
|
13
|
-
controlResponseSchema,
|
|
14
|
-
restartAgentParamsSchema,
|
|
15
|
-
sendParamsSchema,
|
|
16
|
-
spawnParamsSchema,
|
|
17
|
-
waitParamsSchema,
|
|
18
|
-
} from "../control";
|
|
19
|
-
|
|
20
|
-
describe("controlRequestSchema", () => {
|
|
21
|
-
it("accepts a minimal request (params optional)", () => {
|
|
22
|
-
const r = controlRequestSchema.parse({ v: 1, id: 1, verb: "fleet" });
|
|
23
|
-
expect(r.verb).toBe("fleet");
|
|
24
|
-
expect(r.params).toBeUndefined();
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it("accepts string ids and object params", () => {
|
|
28
|
-
const r = controlRequestSchema.parse({
|
|
29
|
-
v: 1,
|
|
30
|
-
id: "req-7",
|
|
31
|
-
verb: "send",
|
|
32
|
-
params: { session: "s", target: "%1", message: "hi" },
|
|
33
|
-
});
|
|
34
|
-
expect(r.id).toBe("req-7");
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it("keeps verb an OPEN string — unknown verbs parse (dispatch answers them)", () => {
|
|
38
|
-
expect(controlRequestSchema.parse({ v: 1, id: 1, verb: "verb-from-the-future" }).verb).toBe(
|
|
39
|
-
"verb-from-the-future",
|
|
40
|
-
);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it("rejects a wrong or missing version", () => {
|
|
44
|
-
expect(() => controlRequestSchema.parse({ v: 2, id: 1, verb: "fleet" })).toThrow();
|
|
45
|
-
expect(() => controlRequestSchema.parse({ id: 1, verb: "fleet" })).toThrow();
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it("rejects a missing id or empty verb", () => {
|
|
49
|
-
expect(() => controlRequestSchema.parse({ v: 1, verb: "fleet" })).toThrow();
|
|
50
|
-
expect(() => controlRequestSchema.parse({ v: 1, id: 1, verb: "" })).toThrow();
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
describe("controlResponseSchema", () => {
|
|
55
|
-
it("accepts an ok response with arbitrary data", () => {
|
|
56
|
-
const r = controlResponseSchema.parse({ v: 1, id: 3, ok: true, data: { projects: [] } });
|
|
57
|
-
expect(r.ok).toBe(true);
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it("accepts an error response with a null id (uncorrelatable frame)", () => {
|
|
61
|
-
const r = controlResponseSchema.parse({
|
|
62
|
-
v: 1,
|
|
63
|
-
id: null,
|
|
64
|
-
ok: false,
|
|
65
|
-
error: { code: "bad-request", message: "unparseable frame" },
|
|
66
|
-
});
|
|
67
|
-
expect(r.ok).toBe(false);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it("rejects an error response without the error object", () => {
|
|
71
|
-
expect(() => controlResponseSchema.parse({ v: 1, id: 1, ok: false })).toThrow();
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
describe("controlEventSchema + agentStatusEventSchema", () => {
|
|
76
|
-
it("accepts an event frame and its agent-status payload", () => {
|
|
77
|
-
const frame = controlEventSchema.parse({
|
|
78
|
-
v: CONTROL_PROTOCOL_VERSION,
|
|
79
|
-
event: "agent-status",
|
|
80
|
-
data: { ts: "2026-07-10T12:00:00Z", session: "zz-x", from: null, to: "working" },
|
|
81
|
-
});
|
|
82
|
-
const ev = agentStatusEventSchema.parse(frame.data);
|
|
83
|
-
expect(ev.from).toBeNull();
|
|
84
|
-
expect(ev.to).toBe("working");
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it("rejects an unknown status in the payload", () => {
|
|
88
|
-
expect(() =>
|
|
89
|
-
agentStatusEventSchema.parse({ ts: "t", session: "s", from: null, to: "sleeping" }),
|
|
90
|
-
).toThrow();
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
describe("waitParamsSchema", () => {
|
|
95
|
-
it("accepts both kinds", () => {
|
|
96
|
-
expect(
|
|
97
|
-
waitParamsSchema.parse({ kind: "agent-status", session: "s", status: "done" }).kind,
|
|
98
|
-
).toBe("agent-status");
|
|
99
|
-
expect(waitParamsSchema.parse({ kind: "output", target: "%1", match: "ok" }).kind).toBe(
|
|
100
|
-
"output",
|
|
101
|
-
);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
it("caps timeoutMs", () => {
|
|
105
|
-
expect(() =>
|
|
106
|
-
waitParamsSchema.parse({
|
|
107
|
-
kind: "output",
|
|
108
|
-
target: "%1",
|
|
109
|
-
match: "ok",
|
|
110
|
-
timeoutMs: CONTROL_WAIT_MAX_TIMEOUT_MS + 1,
|
|
111
|
-
}),
|
|
112
|
-
).toThrow();
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
describe("spawnParamsSchema", () => {
|
|
117
|
-
it("requires exactly one of kind/command", () => {
|
|
118
|
-
expect(() => spawnParamsSchema.parse({ session: "s" })).toThrow();
|
|
119
|
-
expect(() => spawnParamsSchema.parse({ session: "s", kind: "claude", command: "x" })).toThrow();
|
|
120
|
-
expect(spawnParamsSchema.parse({ session: "s", kind: "claude" }).kind).toBe("claude");
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
it("requires a session or a sessionName", () => {
|
|
124
|
-
expect(() => spawnParamsSchema.parse({ kind: "claude" })).toThrow();
|
|
125
|
-
expect(spawnParamsSchema.parse({ sessionName: "zz-new", kind: "claude" }).sessionName).toBe(
|
|
126
|
-
"zz-new",
|
|
127
|
-
);
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
it("requires paneId for split placements only", () => {
|
|
131
|
-
expect(() =>
|
|
132
|
-
spawnParamsSchema.parse({ session: "s", kind: "claude", placement: "split-h" }),
|
|
133
|
-
).toThrow();
|
|
134
|
-
expect(
|
|
135
|
-
spawnParamsSchema.parse({ session: "s", kind: "claude", placement: "window" }).placement,
|
|
136
|
-
).toBe("window");
|
|
137
|
-
});
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
describe("sendParamsSchema / restartAgentParamsSchema", () => {
|
|
141
|
-
it("send requires session, target and a non-empty message", () => {
|
|
142
|
-
expect(() => sendParamsSchema.parse({ session: "s", target: "%1", message: "" })).toThrow();
|
|
143
|
-
expect(sendParamsSchema.parse({ session: "s", target: "%1", message: "go" }).noEnter).toBe(
|
|
144
|
-
undefined,
|
|
145
|
-
);
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
it("restart requires kind or command", () => {
|
|
149
|
-
expect(() => restartAgentParamsSchema.parse({ paneId: "%1" })).toThrow();
|
|
150
|
-
expect(restartAgentParamsSchema.parse({ paneId: "%1", command: "claude" }).command).toBe(
|
|
151
|
-
"claude",
|
|
152
|
-
);
|
|
153
|
-
});
|
|
154
|
-
});
|