@ai-matrx/desktop-protocol 0.4.0 → 0.5.0

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/dist/index.d.cts CHANGED
@@ -1,13 +1,19 @@
1
1
  import { z } from 'zod';
2
- export { B as BEARER_PREFIX, e as CancelMsg, f as ClientToCoreMsg, C as ClientType, g as CloseCode, h as CloseCodeValue, j as CoreToClientMsg, k as CreditMsg, D as DesktopProtocolError, d as EVENTS, l as EndMsg, E as EndReason, m as ErrorCode, n as ErrorCodeName, o as ErrorData, p as ErrorMsg, q as ErrorReason, r as ErrorReasonName, s as EventMsg, t as EventName, F as FsPatchEditFailure, H as HelloMsg, L as Limits, N as NAMED_SCHEMAS, u as NamedSchemaId, c as OPS, v as OpDescriptor, O as OpName, a as OpParams, b as OpResult, w as OpSpec, P as PING_TEXT, x as PONG_TEXT, y as ProtocolErrorBody, R as RelayMsg, z as RequestMsg, A as ResponseMsg, G as SUBPROTOCOL, S as StreamMeta, I as StreamMsg, W as Welcome, i as isDesktopProtocolError } from './registry-CI-NpQ6L.cjs';
2
+ import { O as OpName } from './registry-BeY9D7h0.cjs';
3
+ export { B as BEARER_PREFIX, e as CancelMsg, f as ClientToCoreMsg, C as ClientType, g as CloseCode, h as CloseCodeValue, j as CoreToClientMsg, k as CreditMsg, D as DesktopProtocolError, d as EVENTS, l as EndMsg, E as EndReason, m as ErrorCode, n as ErrorCodeName, o as ErrorData, p as ErrorMsg, q as ErrorReason, r as ErrorReasonName, s as EventMsg, t as EventName, F as FsPatchEditFailure, H as HelloMsg, L as Limits, N as NAMED_SCHEMAS, u as NamedSchemaId, c as OPS, v as OpDescriptor, a as OpParams, b as OpResult, w as OpSpec, P as PING_TEXT, x as PONG_TEXT, y as ProtocolErrorBody, R as RelayMsg, z as RequestMsg, A as ResponseMsg, G as SUBPROTOCOL, S as StreamMeta, I as StreamMsg, W as Welcome, i as isDesktopProtocolError } from './registry-BeY9D7h0.cjs';
3
4
  export { BROADCAST_CID, DecodedFrame, FRAME_HEADER_BYTES, FRAME_STRUCT_FORMAT, FRAME_VERSION, FrameChannel, FrameChannelValue, FrameFlag, assertFrameHeader, connectionEndFrame, decodeFrame, encodeFrame, hasFlag, isConnectionEnd, readCid, stampCid } from './frame.cjs';
4
5
 
5
6
  /** @ai-matrx/desktop-protocol — version and primitive schemas. Schema source: lint-enforced rules in scripts/check-schema-source.mjs. */
6
7
 
7
8
  declare const PROTOCOL_MAJOR: 1;
8
- declare const PROTOCOL_MINOR: 0;
9
+ /**
10
+ * Minor history (same major = compatible; see src/versioning.ts for the rule and FIELDS_SINCE):
11
+ * 1.0 — the first contract.
12
+ * 1.1 — fs.patch per-edit results; /call reports the negotiated version.
13
+ */
14
+ declare const PROTOCOL_MINOR: 1;
9
15
  /** This package's version as the wire spells it ("major.minor"): hello, welcome, relay status. */
10
- declare const PROTOCOL_VERSION: "1.0";
16
+ declare const PROTOCOL_VERSION: "1.1";
11
17
  /** Internal building blocks — deliberately unnamed in $defs (inlined wherever used). */
12
18
  declare const u32: z.ZodInt;
13
19
  declare const nonNegInt: z.ZodInt;
@@ -377,7 +383,7 @@ declare const FsPatchResult: z.ZodObject<{
377
383
  applied: z.ZodInt;
378
384
  size: z.ZodInt;
379
385
  mtime_ms: z.ZodInt;
380
- edits_applied: z.ZodArray<z.ZodObject<{
386
+ edits_applied: z.ZodOptional<z.ZodArray<z.ZodObject<{
381
387
  edit_index: z.ZodInt;
382
388
  mode: z.ZodEnum<{
383
389
  replace_all: "replace_all";
@@ -385,11 +391,11 @@ declare const FsPatchResult: z.ZodObject<{
385
391
  replace: "replace";
386
392
  }>;
387
393
  matches_replaced: z.ZodOptional<z.ZodInt>;
388
- }, z.core.$strict>>;
389
- edits_failed: z.ZodArray<z.ZodObject<{
394
+ }, z.core.$strict>>>;
395
+ edits_failed: z.ZodOptional<z.ZodArray<z.ZodObject<{
390
396
  edit_index: z.ZodInt;
391
397
  reason: z.ZodString;
392
- }, z.core.$strict>>;
398
+ }, z.core.$strict>>>;
393
399
  }, z.core.$strict>;
394
400
  type FsPatchResult = z.output<typeof FsPatchResult>;
395
401
  /** One edit fs.patch applied — the daemon's `edits_applied[]` entry, verbatim. */
@@ -901,6 +907,11 @@ type SessionControlChangedEvent = z.output<typeof SessionControlChangedEvent>;
901
907
 
902
908
  /** @ai-matrx/desktop-protocol — cap relay. Schema source: lint-enforced rules in scripts/check-schema-source.mjs. */
903
909
 
910
+ /**
911
+ * The caller of /call announces the newest protocol it reads in this request header; the relay
912
+ * includes fields newer than 1.0 only when the announced version knows them (src/versioning.ts).
913
+ */
914
+ declare const RELAY_CALL_VERSION_HEADER: "x-matrx-protocol-version";
904
915
  /**
905
916
  * How the relay runs one /call on the device: a fresh cid (its own connection) carrying exactly
906
917
  * RelayCallHello then RelayCallEnvelope, answered on that cid by response/error with id "call"
@@ -930,6 +941,7 @@ type RelayCallRequest = z.output<typeof RelayCallRequest>;
930
941
  declare const RelayCallResponse: z.ZodDiscriminatedUnion<[z.ZodObject<{
931
942
  ok: z.ZodLiteral<true>;
932
943
  result: z.ZodUnknown;
944
+ protocol_version: z.ZodOptional<z.ZodString>;
933
945
  }, z.core.$strict>, z.ZodObject<{
934
946
  ok: z.ZodLiteral<false>;
935
947
  error: z.ZodObject<{
@@ -991,6 +1003,7 @@ declare const RelayCallResponse: z.ZodDiscriminatedUnion<[z.ZodObject<{
991
1003
  }, z.core.$strict>>;
992
1004
  }, z.core.$strict>>;
993
1005
  }, z.core.$strict>;
1006
+ protocol_version: z.ZodOptional<z.ZodString>;
994
1007
  }, z.core.$strict>], "ok">;
995
1008
  type RelayCallResponse = z.output<typeof RelayCallResponse>;
996
1009
  /** HTTP GET /v1/devices/{device_id}/status (owner JWT). */
@@ -1018,4 +1031,53 @@ declare const RelayCallEnvelope: z.ZodObject<{
1018
1031
  }, z.core.$strict>;
1019
1032
  type RelayCallEnvelope = z.output<typeof RelayCallEnvelope>;
1020
1033
 
1021
- export { AbsPath, DEFAULT_MAX_FRAME_PAYLOAD_BYTES, DEFAULT_MAX_MESSAGE_BYTES, DEFAULT_WINDOW_BYTES, DeviceId, ExecCwdEvent, ExecExitedEvent, ExecListParams, ExecListResult, ExecPtyKillParams, ExecPtyKillResult, ExecPtyResizeParams, ExecPtyResizeResult, ExecPtySignalParams, ExecPtySignalResult, ExecPtyStartParams, ExecPtyStartResult, ExecPtyWriteParams, ExecPtyWriteResult, ExecRunParams, ExecRunResult, ExecTitleEvent, FrameHeader, FsChange, FsChangedEvent, FsDeleteParams, FsDeleteResult, FsEncoding, FsEntry, FsKind, FsListParams, FsListResult, FsMkdirParams, FsMkdirResult, FsMoveParams, FsMoveResult, FsPatchEditApplied, FsPatchParams, FsPatchResult, FsReadParams, FsReadResult, FsReadStreamParams, FsReadStreamResult, FsSearchContentParams, FsSearchContentResult, FsSearchPathsParams, FsSearchPathsResult, FsStatParams, FsStatResult, FsWatchParams, FsWatchResult, FsWriteParams, FsWriteResult, OsPermissionName, PROTOCOL_MAJOR, PROTOCOL_MINOR, PROTOCOL_VERSION, ProtocolVersion, PtyInfo, RELAY_CALL_HELLO_ID, RELAY_CALL_REQUEST_ID, RelayAuthExpiringEvent, RelayCallEnvelope, RelayCallHello, RelayCallRequest, RelayCallResponse, RelayDeviceStatusEvent, RelayHopConnectionEnd, RelayHopEnvelopeHeader, RelayStatusResponse, RequestId, ResourceId, ResourceInfo, SessionAttachParams, SessionAttachResult, SessionControlChangedEvent, SessionDetachParams, SessionDetachResult, SessionListParams, SessionListResult, SessionReleaseParams, SessionReleaseResult, Signal, SysinfoGetParams, SysinfoGetResult, epochMs, nonNegInt, u32 };
1034
+ /**
1035
+ * Version skew is the normal state: a phone, the server and a desktop app in the field run
1036
+ * different package versions, and a minor protocol bump must never make any of them fail.
1037
+ *
1038
+ * THE RULE (enforced by src/versioning.test.ts against generated/baseline-1.0.json):
1039
+ * 1. Within a major, a minor may only ADD. A field added after x.0 is OPTIONAL in the schema
1040
+ * (an older peer omits it) and is listed in FIELDS_SINCE with the minor that added it.
1041
+ * 2. A writer never sends a field newer than the version its peer negotiated (hello/welcome, or
1042
+ * the /call version header): older peers' strict schemas refuse unknown keys. `forPeer`
1043
+ * does the stripping; the core's Router applies it to every result and error it sends.
1044
+ * 3. A reader that needs a newer field checks the peer's version and says so loudly when the
1045
+ * peer is older (e.g. aidream's local_proxy marks a patch answer from a 1.0 app).
1046
+ */
1047
+
1048
+ /**
1049
+ * Fields added after x.0, by schema location: a named schema (`FsPatchResult`), a property path
1050
+ * inside one (`ProtocolErrorBody.data`), or a union branch (`RelayCallResponse|0`).
1051
+ */
1052
+ declare const FIELDS_SINCE: {
1053
+ readonly FsPatchResult: {
1054
+ readonly edits_applied: "1.1";
1055
+ readonly edits_failed: "1.1";
1056
+ };
1057
+ readonly "ProtocolErrorBody.data": {
1058
+ readonly edits_failed: "1.1";
1059
+ };
1060
+ readonly "RelayCallResponse|0": {
1061
+ readonly protocol_version: "1.1";
1062
+ };
1063
+ readonly "RelayCallResponse|1": {
1064
+ readonly protocol_version: "1.1";
1065
+ };
1066
+ };
1067
+ type FieldsSincePath = keyof typeof FIELDS_SINCE;
1068
+ /** "1.10" > "1.9". Same-major comparison of "major.minor" strings. */
1069
+ declare function compareVersions(a: string, b: string): number;
1070
+ /** True when a peer at `version` knows a field added in `since`. */
1071
+ declare function knows(version: string, since: string): boolean;
1072
+ /** The version two peers speak: the lower minor within this major. */
1073
+ declare function negotiate(peerVersion: string): string;
1074
+ /**
1075
+ * What to send a peer that negotiated `version`: `result` of `op`, or an error body, with every
1076
+ * field newer than that version removed (rule 2). Unchanged for a current peer.
1077
+ */
1078
+ declare function forPeer(op: OpName, part: "result", value: unknown, version: string): unknown;
1079
+ declare function forPeer(op: OpName | null, part: "error", value: unknown, version: string): unknown;
1080
+ /** Every op whose result has a versioned field is wired into forPeer (checked by the test). */
1081
+ declare const VERSIONED_RESULT_OPS: readonly OpName[];
1082
+
1083
+ export { AbsPath, DEFAULT_MAX_FRAME_PAYLOAD_BYTES, DEFAULT_MAX_MESSAGE_BYTES, DEFAULT_WINDOW_BYTES, DeviceId, ExecCwdEvent, ExecExitedEvent, ExecListParams, ExecListResult, ExecPtyKillParams, ExecPtyKillResult, ExecPtyResizeParams, ExecPtyResizeResult, ExecPtySignalParams, ExecPtySignalResult, ExecPtyStartParams, ExecPtyStartResult, ExecPtyWriteParams, ExecPtyWriteResult, ExecRunParams, ExecRunResult, ExecTitleEvent, FIELDS_SINCE, type FieldsSincePath, FrameHeader, FsChange, FsChangedEvent, FsDeleteParams, FsDeleteResult, FsEncoding, FsEntry, FsKind, FsListParams, FsListResult, FsMkdirParams, FsMkdirResult, FsMoveParams, FsMoveResult, FsPatchEditApplied, FsPatchParams, FsPatchResult, FsReadParams, FsReadResult, FsReadStreamParams, FsReadStreamResult, FsSearchContentParams, FsSearchContentResult, FsSearchPathsParams, FsSearchPathsResult, FsStatParams, FsStatResult, FsWatchParams, FsWatchResult, FsWriteParams, FsWriteResult, OpName, OsPermissionName, PROTOCOL_MAJOR, PROTOCOL_MINOR, PROTOCOL_VERSION, ProtocolVersion, PtyInfo, RELAY_CALL_HELLO_ID, RELAY_CALL_REQUEST_ID, RELAY_CALL_VERSION_HEADER, RelayAuthExpiringEvent, RelayCallEnvelope, RelayCallHello, RelayCallRequest, RelayCallResponse, RelayDeviceStatusEvent, RelayHopConnectionEnd, RelayHopEnvelopeHeader, RelayStatusResponse, RequestId, ResourceId, ResourceInfo, SessionAttachParams, SessionAttachResult, SessionControlChangedEvent, SessionDetachParams, SessionDetachResult, SessionListParams, SessionListResult, SessionReleaseParams, SessionReleaseResult, Signal, SysinfoGetParams, SysinfoGetResult, VERSIONED_RESULT_OPS, compareVersions, epochMs, forPeer, knows, negotiate, nonNegInt, u32 };
package/dist/index.d.ts CHANGED
@@ -1,13 +1,19 @@
1
1
  import { z } from 'zod';
2
- export { B as BEARER_PREFIX, e as CancelMsg, f as ClientToCoreMsg, C as ClientType, g as CloseCode, h as CloseCodeValue, j as CoreToClientMsg, k as CreditMsg, D as DesktopProtocolError, d as EVENTS, l as EndMsg, E as EndReason, m as ErrorCode, n as ErrorCodeName, o as ErrorData, p as ErrorMsg, q as ErrorReason, r as ErrorReasonName, s as EventMsg, t as EventName, F as FsPatchEditFailure, H as HelloMsg, L as Limits, N as NAMED_SCHEMAS, u as NamedSchemaId, c as OPS, v as OpDescriptor, O as OpName, a as OpParams, b as OpResult, w as OpSpec, P as PING_TEXT, x as PONG_TEXT, y as ProtocolErrorBody, R as RelayMsg, z as RequestMsg, A as ResponseMsg, G as SUBPROTOCOL, S as StreamMeta, I as StreamMsg, W as Welcome, i as isDesktopProtocolError } from './registry-CI-NpQ6L.js';
2
+ import { O as OpName } from './registry-BeY9D7h0.js';
3
+ export { B as BEARER_PREFIX, e as CancelMsg, f as ClientToCoreMsg, C as ClientType, g as CloseCode, h as CloseCodeValue, j as CoreToClientMsg, k as CreditMsg, D as DesktopProtocolError, d as EVENTS, l as EndMsg, E as EndReason, m as ErrorCode, n as ErrorCodeName, o as ErrorData, p as ErrorMsg, q as ErrorReason, r as ErrorReasonName, s as EventMsg, t as EventName, F as FsPatchEditFailure, H as HelloMsg, L as Limits, N as NAMED_SCHEMAS, u as NamedSchemaId, c as OPS, v as OpDescriptor, a as OpParams, b as OpResult, w as OpSpec, P as PING_TEXT, x as PONG_TEXT, y as ProtocolErrorBody, R as RelayMsg, z as RequestMsg, A as ResponseMsg, G as SUBPROTOCOL, S as StreamMeta, I as StreamMsg, W as Welcome, i as isDesktopProtocolError } from './registry-BeY9D7h0.js';
3
4
  export { BROADCAST_CID, DecodedFrame, FRAME_HEADER_BYTES, FRAME_STRUCT_FORMAT, FRAME_VERSION, FrameChannel, FrameChannelValue, FrameFlag, assertFrameHeader, connectionEndFrame, decodeFrame, encodeFrame, hasFlag, isConnectionEnd, readCid, stampCid } from './frame.js';
4
5
 
5
6
  /** @ai-matrx/desktop-protocol — version and primitive schemas. Schema source: lint-enforced rules in scripts/check-schema-source.mjs. */
6
7
 
7
8
  declare const PROTOCOL_MAJOR: 1;
8
- declare const PROTOCOL_MINOR: 0;
9
+ /**
10
+ * Minor history (same major = compatible; see src/versioning.ts for the rule and FIELDS_SINCE):
11
+ * 1.0 — the first contract.
12
+ * 1.1 — fs.patch per-edit results; /call reports the negotiated version.
13
+ */
14
+ declare const PROTOCOL_MINOR: 1;
9
15
  /** This package's version as the wire spells it ("major.minor"): hello, welcome, relay status. */
10
- declare const PROTOCOL_VERSION: "1.0";
16
+ declare const PROTOCOL_VERSION: "1.1";
11
17
  /** Internal building blocks — deliberately unnamed in $defs (inlined wherever used). */
12
18
  declare const u32: z.ZodInt;
13
19
  declare const nonNegInt: z.ZodInt;
@@ -377,7 +383,7 @@ declare const FsPatchResult: z.ZodObject<{
377
383
  applied: z.ZodInt;
378
384
  size: z.ZodInt;
379
385
  mtime_ms: z.ZodInt;
380
- edits_applied: z.ZodArray<z.ZodObject<{
386
+ edits_applied: z.ZodOptional<z.ZodArray<z.ZodObject<{
381
387
  edit_index: z.ZodInt;
382
388
  mode: z.ZodEnum<{
383
389
  replace_all: "replace_all";
@@ -385,11 +391,11 @@ declare const FsPatchResult: z.ZodObject<{
385
391
  replace: "replace";
386
392
  }>;
387
393
  matches_replaced: z.ZodOptional<z.ZodInt>;
388
- }, z.core.$strict>>;
389
- edits_failed: z.ZodArray<z.ZodObject<{
394
+ }, z.core.$strict>>>;
395
+ edits_failed: z.ZodOptional<z.ZodArray<z.ZodObject<{
390
396
  edit_index: z.ZodInt;
391
397
  reason: z.ZodString;
392
- }, z.core.$strict>>;
398
+ }, z.core.$strict>>>;
393
399
  }, z.core.$strict>;
394
400
  type FsPatchResult = z.output<typeof FsPatchResult>;
395
401
  /** One edit fs.patch applied — the daemon's `edits_applied[]` entry, verbatim. */
@@ -901,6 +907,11 @@ type SessionControlChangedEvent = z.output<typeof SessionControlChangedEvent>;
901
907
 
902
908
  /** @ai-matrx/desktop-protocol — cap relay. Schema source: lint-enforced rules in scripts/check-schema-source.mjs. */
903
909
 
910
+ /**
911
+ * The caller of /call announces the newest protocol it reads in this request header; the relay
912
+ * includes fields newer than 1.0 only when the announced version knows them (src/versioning.ts).
913
+ */
914
+ declare const RELAY_CALL_VERSION_HEADER: "x-matrx-protocol-version";
904
915
  /**
905
916
  * How the relay runs one /call on the device: a fresh cid (its own connection) carrying exactly
906
917
  * RelayCallHello then RelayCallEnvelope, answered on that cid by response/error with id "call"
@@ -930,6 +941,7 @@ type RelayCallRequest = z.output<typeof RelayCallRequest>;
930
941
  declare const RelayCallResponse: z.ZodDiscriminatedUnion<[z.ZodObject<{
931
942
  ok: z.ZodLiteral<true>;
932
943
  result: z.ZodUnknown;
944
+ protocol_version: z.ZodOptional<z.ZodString>;
933
945
  }, z.core.$strict>, z.ZodObject<{
934
946
  ok: z.ZodLiteral<false>;
935
947
  error: z.ZodObject<{
@@ -991,6 +1003,7 @@ declare const RelayCallResponse: z.ZodDiscriminatedUnion<[z.ZodObject<{
991
1003
  }, z.core.$strict>>;
992
1004
  }, z.core.$strict>>;
993
1005
  }, z.core.$strict>;
1006
+ protocol_version: z.ZodOptional<z.ZodString>;
994
1007
  }, z.core.$strict>], "ok">;
995
1008
  type RelayCallResponse = z.output<typeof RelayCallResponse>;
996
1009
  /** HTTP GET /v1/devices/{device_id}/status (owner JWT). */
@@ -1018,4 +1031,53 @@ declare const RelayCallEnvelope: z.ZodObject<{
1018
1031
  }, z.core.$strict>;
1019
1032
  type RelayCallEnvelope = z.output<typeof RelayCallEnvelope>;
1020
1033
 
1021
- export { AbsPath, DEFAULT_MAX_FRAME_PAYLOAD_BYTES, DEFAULT_MAX_MESSAGE_BYTES, DEFAULT_WINDOW_BYTES, DeviceId, ExecCwdEvent, ExecExitedEvent, ExecListParams, ExecListResult, ExecPtyKillParams, ExecPtyKillResult, ExecPtyResizeParams, ExecPtyResizeResult, ExecPtySignalParams, ExecPtySignalResult, ExecPtyStartParams, ExecPtyStartResult, ExecPtyWriteParams, ExecPtyWriteResult, ExecRunParams, ExecRunResult, ExecTitleEvent, FrameHeader, FsChange, FsChangedEvent, FsDeleteParams, FsDeleteResult, FsEncoding, FsEntry, FsKind, FsListParams, FsListResult, FsMkdirParams, FsMkdirResult, FsMoveParams, FsMoveResult, FsPatchEditApplied, FsPatchParams, FsPatchResult, FsReadParams, FsReadResult, FsReadStreamParams, FsReadStreamResult, FsSearchContentParams, FsSearchContentResult, FsSearchPathsParams, FsSearchPathsResult, FsStatParams, FsStatResult, FsWatchParams, FsWatchResult, FsWriteParams, FsWriteResult, OsPermissionName, PROTOCOL_MAJOR, PROTOCOL_MINOR, PROTOCOL_VERSION, ProtocolVersion, PtyInfo, RELAY_CALL_HELLO_ID, RELAY_CALL_REQUEST_ID, RelayAuthExpiringEvent, RelayCallEnvelope, RelayCallHello, RelayCallRequest, RelayCallResponse, RelayDeviceStatusEvent, RelayHopConnectionEnd, RelayHopEnvelopeHeader, RelayStatusResponse, RequestId, ResourceId, ResourceInfo, SessionAttachParams, SessionAttachResult, SessionControlChangedEvent, SessionDetachParams, SessionDetachResult, SessionListParams, SessionListResult, SessionReleaseParams, SessionReleaseResult, Signal, SysinfoGetParams, SysinfoGetResult, epochMs, nonNegInt, u32 };
1034
+ /**
1035
+ * Version skew is the normal state: a phone, the server and a desktop app in the field run
1036
+ * different package versions, and a minor protocol bump must never make any of them fail.
1037
+ *
1038
+ * THE RULE (enforced by src/versioning.test.ts against generated/baseline-1.0.json):
1039
+ * 1. Within a major, a minor may only ADD. A field added after x.0 is OPTIONAL in the schema
1040
+ * (an older peer omits it) and is listed in FIELDS_SINCE with the minor that added it.
1041
+ * 2. A writer never sends a field newer than the version its peer negotiated (hello/welcome, or
1042
+ * the /call version header): older peers' strict schemas refuse unknown keys. `forPeer`
1043
+ * does the stripping; the core's Router applies it to every result and error it sends.
1044
+ * 3. A reader that needs a newer field checks the peer's version and says so loudly when the
1045
+ * peer is older (e.g. aidream's local_proxy marks a patch answer from a 1.0 app).
1046
+ */
1047
+
1048
+ /**
1049
+ * Fields added after x.0, by schema location: a named schema (`FsPatchResult`), a property path
1050
+ * inside one (`ProtocolErrorBody.data`), or a union branch (`RelayCallResponse|0`).
1051
+ */
1052
+ declare const FIELDS_SINCE: {
1053
+ readonly FsPatchResult: {
1054
+ readonly edits_applied: "1.1";
1055
+ readonly edits_failed: "1.1";
1056
+ };
1057
+ readonly "ProtocolErrorBody.data": {
1058
+ readonly edits_failed: "1.1";
1059
+ };
1060
+ readonly "RelayCallResponse|0": {
1061
+ readonly protocol_version: "1.1";
1062
+ };
1063
+ readonly "RelayCallResponse|1": {
1064
+ readonly protocol_version: "1.1";
1065
+ };
1066
+ };
1067
+ type FieldsSincePath = keyof typeof FIELDS_SINCE;
1068
+ /** "1.10" > "1.9". Same-major comparison of "major.minor" strings. */
1069
+ declare function compareVersions(a: string, b: string): number;
1070
+ /** True when a peer at `version` knows a field added in `since`. */
1071
+ declare function knows(version: string, since: string): boolean;
1072
+ /** The version two peers speak: the lower minor within this major. */
1073
+ declare function negotiate(peerVersion: string): string;
1074
+ /**
1075
+ * What to send a peer that negotiated `version`: `result` of `op`, or an error body, with every
1076
+ * field newer than that version removed (rule 2). Unchanged for a current peer.
1077
+ */
1078
+ declare function forPeer(op: OpName, part: "result", value: unknown, version: string): unknown;
1079
+ declare function forPeer(op: OpName | null, part: "error", value: unknown, version: string): unknown;
1080
+ /** Every op whose result has a versioned field is wired into forPeer (checked by the test). */
1081
+ declare const VERSIONED_RESULT_OPS: readonly OpName[];
1082
+
1083
+ export { AbsPath, DEFAULT_MAX_FRAME_PAYLOAD_BYTES, DEFAULT_MAX_MESSAGE_BYTES, DEFAULT_WINDOW_BYTES, DeviceId, ExecCwdEvent, ExecExitedEvent, ExecListParams, ExecListResult, ExecPtyKillParams, ExecPtyKillResult, ExecPtyResizeParams, ExecPtyResizeResult, ExecPtySignalParams, ExecPtySignalResult, ExecPtyStartParams, ExecPtyStartResult, ExecPtyWriteParams, ExecPtyWriteResult, ExecRunParams, ExecRunResult, ExecTitleEvent, FIELDS_SINCE, type FieldsSincePath, FrameHeader, FsChange, FsChangedEvent, FsDeleteParams, FsDeleteResult, FsEncoding, FsEntry, FsKind, FsListParams, FsListResult, FsMkdirParams, FsMkdirResult, FsMoveParams, FsMoveResult, FsPatchEditApplied, FsPatchParams, FsPatchResult, FsReadParams, FsReadResult, FsReadStreamParams, FsReadStreamResult, FsSearchContentParams, FsSearchContentResult, FsSearchPathsParams, FsSearchPathsResult, FsStatParams, FsStatResult, FsWatchParams, FsWatchResult, FsWriteParams, FsWriteResult, OpName, OsPermissionName, PROTOCOL_MAJOR, PROTOCOL_MINOR, PROTOCOL_VERSION, ProtocolVersion, PtyInfo, RELAY_CALL_HELLO_ID, RELAY_CALL_REQUEST_ID, RELAY_CALL_VERSION_HEADER, RelayAuthExpiringEvent, RelayCallEnvelope, RelayCallHello, RelayCallRequest, RelayCallResponse, RelayDeviceStatusEvent, RelayHopConnectionEnd, RelayHopEnvelopeHeader, RelayStatusResponse, RequestId, ResourceId, ResourceInfo, SessionAttachParams, SessionAttachResult, SessionControlChangedEvent, SessionDetachParams, SessionDetachResult, SessionListParams, SessionListResult, SessionReleaseParams, SessionReleaseResult, Signal, SysinfoGetParams, SysinfoGetResult, VERSIONED_RESULT_OPS, compareVersions, epochMs, forPeer, knows, negotiate, nonNegInt, u32 };
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/schema/primitives.ts
2
2
  import { z } from "zod";
3
3
  var PROTOCOL_MAJOR = 1;
4
- var PROTOCOL_MINOR = 0;
4
+ var PROTOCOL_MINOR = 1;
5
5
  var PROTOCOL_VERSION = `${PROTOCOL_MAJOR}.${PROTOCOL_MINOR}`;
6
6
  var ProtocolVersion = z.string().regex(/^[1-9][0-9]{0,2}\.[0-9]{1,3}$/);
7
7
  var RequestId = z.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/);
@@ -495,8 +495,10 @@ var FsPatchResult = z6.strictObject({
495
495
  applied: nonNegInt,
496
496
  size: nonNegInt,
497
497
  mtime_ms: epochMs,
498
- edits_applied: z6.array(FsPatchEditApplied).max(256),
499
- edits_failed: z6.array(FsPatchEditFailure).max(256)
498
+ /** Since 1.1 (FIELDS_SINCE): a 1.0 app sends only `applied`. Always sent to a ≥1.1 peer. */
499
+ edits_applied: z6.array(FsPatchEditApplied).max(256).optional(),
500
+ /** Since 1.1 (FIELDS_SINCE). */
501
+ edits_failed: z6.array(FsPatchEditFailure).max(256).optional()
500
502
  });
501
503
  var FsSearchPathsParams = z6.strictObject({
502
504
  pattern: z6.string().min(1).max(512),
@@ -647,9 +649,20 @@ var RelayCallRequest = z9.strictObject({
647
649
  params: z9.unknown(),
648
650
  timeout_ms: z9.int().min(100).max(37e5).default(7e4)
649
651
  });
652
+ var RELAY_CALL_VERSION_HEADER = "x-matrx-protocol-version";
650
653
  var RelayCallResponse = z9.discriminatedUnion("ok", [
651
- z9.strictObject({ ok: z9.literal(true), result: z9.unknown() }),
652
- z9.strictObject({ ok: z9.literal(false), error: ProtocolErrorBody })
654
+ z9.strictObject({
655
+ ok: z9.literal(true),
656
+ result: z9.unknown(),
657
+ /** Since 1.1: the version the device negotiated for this call (its welcome). */
658
+ protocol_version: ProtocolVersion.optional()
659
+ }),
660
+ z9.strictObject({
661
+ ok: z9.literal(false),
662
+ error: ProtocolErrorBody,
663
+ /** Since 1.1, as above (absent when the device never answered hello). */
664
+ protocol_version: ProtocolVersion.optional()
665
+ })
653
666
  ]);
654
667
  var RELAY_CALL_HELLO_ID = "hello";
655
668
  var RELAY_CALL_REQUEST_ID = "call";
@@ -804,6 +817,51 @@ var NAMED_SCHEMAS = {
804
817
  RelayHopConnectionEnd,
805
818
  CloseCodeValue
806
819
  };
820
+
821
+ // src/versioning.ts
822
+ var FIELDS_SINCE = {
823
+ FsPatchResult: { edits_applied: "1.1", edits_failed: "1.1" },
824
+ "ProtocolErrorBody.data": { edits_failed: "1.1" },
825
+ "RelayCallResponse|0": { protocol_version: "1.1" },
826
+ "RelayCallResponse|1": { protocol_version: "1.1" }
827
+ };
828
+ function compareVersions(a, b) {
829
+ const [am = 0, an = 0] = a.split(".").map(Number);
830
+ const [bm = 0, bn = 0] = b.split(".").map(Number);
831
+ return am - bm || an - bn;
832
+ }
833
+ function knows(version, since) {
834
+ return compareVersions(version, since) >= 0;
835
+ }
836
+ function negotiate(peerVersion) {
837
+ const [major = 0, minor = 0] = peerVersion.split(".").map(Number);
838
+ if (major !== PROTOCOL_MAJOR) return `${PROTOCOL_MAJOR}.0`;
839
+ return `${PROTOCOL_MAJOR}.${Math.min(minor, PROTOCOL_MINOR)}`;
840
+ }
841
+ function strip(value, fields, version) {
842
+ if (!fields || value === null || typeof value !== "object" || Array.isArray(value)) return value;
843
+ let out = null;
844
+ for (const [field, since] of Object.entries(fields)) {
845
+ if (field in value && !knows(version, since)) {
846
+ out ??= { ...value };
847
+ delete out[field];
848
+ }
849
+ }
850
+ return out ?? value;
851
+ }
852
+ var RESULT_PATH = /* @__PURE__ */ new Map([["fs.patch", "FsPatchResult"]]);
853
+ function forPeer(op, part, value, version) {
854
+ if (part === "result") {
855
+ const path = op ? RESULT_PATH.get(op) : void 0;
856
+ return path ? strip(value, FIELDS_SINCE[path], version) : value;
857
+ }
858
+ if (value === null || typeof value !== "object") return value;
859
+ const body = value;
860
+ if (body.data === void 0) return value;
861
+ const data = strip(body.data, FIELDS_SINCE["ProtocolErrorBody.data"], version);
862
+ return data === body.data ? value : { ...body, data };
863
+ }
864
+ var VERSIONED_RESULT_OPS = [...RESULT_PATH.keys()];
807
865
  export {
808
866
  AbsPath,
809
867
  BEARER_PREFIX,
@@ -844,6 +902,7 @@ export {
844
902
  ExecRunParams,
845
903
  ExecRunResult,
846
904
  ExecTitleEvent,
905
+ FIELDS_SINCE,
847
906
  FRAME_HEADER_BYTES,
848
907
  FRAME_STRUCT_FORMAT,
849
908
  FRAME_VERSION,
@@ -897,6 +956,7 @@ export {
897
956
  PtyInfo,
898
957
  RELAY_CALL_HELLO_ID,
899
958
  RELAY_CALL_REQUEST_ID,
959
+ RELAY_CALL_VERSION_HEADER,
900
960
  RelayAuthExpiringEvent,
901
961
  RelayCallEnvelope,
902
962
  RelayCallHello,
@@ -927,15 +987,20 @@ export {
927
987
  StreamMsg,
928
988
  SysinfoGetParams,
929
989
  SysinfoGetResult,
990
+ VERSIONED_RESULT_OPS,
930
991
  Welcome,
931
992
  assertFrameHeader,
993
+ compareVersions,
932
994
  connectionEndFrame,
933
995
  decodeFrame,
934
996
  encodeFrame,
935
997
  epochMs,
998
+ forPeer,
936
999
  hasFlag,
937
1000
  isConnectionEnd,
938
1001
  isDesktopProtocolError,
1002
+ knows,
1003
+ negotiate,
939
1004
  nonNegInt,
940
1005
  readCid,
941
1006
  stampCid,