@ai-matrx/desktop-protocol 0.5.0 → 0.7.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.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
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';
2
+ import { O as OpName } from './registry-Duc_VFN8.js';
3
+ export { B as BEARER_PREFIX, f as CLOSE_RULES, g as CancelMsg, h as ClientToCoreMsg, e as ClientType, j as CloseAction, k as CloseCode, l as CloseCodeValue, C as CloseOutcome, m as CloseRule, n as CoreToClientMsg, o as CreditMsg, D as DesktopProtocolError, d as EVENTS, p as EndMsg, E as EndReason, q as ErrorCode, r as ErrorCodeName, s as ErrorData, t as ErrorMsg, u as ErrorReason, v as ErrorReasonName, w as EventMsg, x as EventName, F as FsPatchEditFailure, H as HelloMsg, L as Limits, N as NAMED_SCHEMAS, y as NamedSchemaId, c as OPS, z as OpDescriptor, a as OpParams, b as OpResult, A as OpSpec, P as PING_TEXT, G as PONG_TEXT, I as ProtocolErrorBody, R as RelayMsg, J as RequestMsg, K as ResponseMsg, M as SUBPROTOCOL, S as StreamMeta, Q as StreamMsg, W as Welcome, T as closeRule, i as isDesktopProtocolError, U as isTerminalClose } from './registry-Duc_VFN8.js';
4
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';
5
5
 
6
6
  /** @ai-matrx/desktop-protocol — version and primitive schemas. Schema source: lint-enforced rules in scripts/check-schema-source.mjs. */
@@ -9,7 +9,8 @@ declare const PROTOCOL_MAJOR: 1;
9
9
  /**
10
10
  * Minor history (same major = compatible; see src/versioning.ts for the rule and FIELDS_SINCE):
11
11
  * 1.0 — the first contract.
12
- * 1.1 — fs.patch per-edit results; /call reports the negotiated version.
12
+ * 1.1 — fs.patch per-edit results; /call reports the negotiated version;
13
+ * device status since_ms is null for a device that never connected.
13
14
  */
14
15
  declare const PROTOCOL_MINOR: 1;
15
16
  /** This package's version as the wire spells it ("major.minor"): hello, welcome, relay status. */
@@ -921,7 +922,7 @@ declare const RELAY_CALL_HELLO_ID: "hello";
921
922
  declare const RELAY_CALL_REQUEST_ID: "call";
922
923
  declare const RelayDeviceStatusEvent: z.ZodObject<{
923
924
  online: z.ZodBoolean;
924
- since_ms: z.ZodInt;
925
+ since_ms: z.ZodNullable<z.ZodInt>;
925
926
  app_version: z.ZodNullable<z.ZodString>;
926
927
  protocol_version: z.ZodNullable<z.ZodString>;
927
928
  }, z.core.$strict>;
@@ -1009,7 +1010,7 @@ type RelayCallResponse = z.output<typeof RelayCallResponse>;
1009
1010
  /** HTTP GET /v1/devices/{device_id}/status (owner JWT). */
1010
1011
  declare const RelayStatusResponse: z.ZodObject<{
1011
1012
  online: z.ZodBoolean;
1012
- since_ms: z.ZodInt;
1013
+ since_ms: z.ZodNullable<z.ZodInt>;
1013
1014
  app_version: z.ZodNullable<z.ZodString>;
1014
1015
  protocol_version: z.ZodNullable<z.ZodString>;
1015
1016
  }, z.core.$strict>;
@@ -1065,6 +1066,28 @@ declare const FIELDS_SINCE: {
1065
1066
  };
1066
1067
  };
1067
1068
  type FieldsSincePath = keyof typeof FIELDS_SINCE;
1069
+ /**
1070
+ * 1.0 fields that a later minor lets be null, and what a peer older than that minor is sent
1071
+ * instead (the value that meant the same thing before). Widening a field any other way is a major.
1072
+ */
1073
+ declare const NULL_SINCE: {
1074
+ readonly "RelayDeviceStatusEvent.since_ms": {
1075
+ readonly since: "1.1";
1076
+ readonly olderPeersGet: 0;
1077
+ };
1078
+ };
1079
+ /** A device status for a reader at `version`: `since_ms` null ("never") becomes 0 before 1.1. */
1080
+ declare function statusForPeer<T extends {
1081
+ since_ms: number | null;
1082
+ }>(status: T, version: string): T;
1083
+ /**
1084
+ * A WebSocket client announces the newest minor it reads at connect time by also offering
1085
+ * `matrx.v<major>.<minor>` beside SUBPROTOCOL (servers still answer SUBPROTOCOL). Before hello is
1086
+ * possible, this is how the relay picks the right shape for its greeting.
1087
+ */
1088
+ declare function versionSubprotocol(version: string): string;
1089
+ /** The version a client announced in its offered subprotocols; "1.0" when it did not. */
1090
+ declare function announcedVersion(offered: readonly string[]): string;
1068
1091
  /** "1.10" > "1.9". Same-major comparison of "major.minor" strings. */
1069
1092
  declare function compareVersions(a: string, b: string): number;
1070
1093
  /** True when a peer at `version` knows a field added in `since`. */
@@ -1080,4 +1103,4 @@ declare function forPeer(op: OpName | null, part: "error", value: unknown, versi
1080
1103
  /** Every op whose result has a versioned field is wired into forPeer (checked by the test). */
1081
1104
  declare const VERSIONED_RESULT_OPS: readonly OpName[];
1082
1105
 
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 };
1106
+ 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, NULL_SINCE, 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, announcedVersion, compareVersions, epochMs, forPeer, knows, negotiate, nonNegInt, statusForPeer, u32, versionSubprotocol };
package/dist/index.js CHANGED
@@ -638,7 +638,11 @@ var SessionControlChangedEvent = z8.strictObject({ controller_client_id: z8.stri
638
638
  import { z as z9 } from "zod";
639
639
  var RelayDeviceStatusEvent = z9.strictObject({
640
640
  online: z9.boolean(),
641
- since_ms: epochMs,
641
+ /**
642
+ * When the device last went online/offline; null = it has never connected (since 1.1 —
643
+ * NULL_SINCE: a 1.0 reader is sent 0, its old meaning).
644
+ */
645
+ since_ms: epochMs.nullable(),
642
646
  app_version: z9.string().max(32).nullable(),
643
647
  protocol_version: ProtocolVersion.nullable()
644
648
  });
@@ -825,6 +829,24 @@ var FIELDS_SINCE = {
825
829
  "RelayCallResponse|0": { protocol_version: "1.1" },
826
830
  "RelayCallResponse|1": { protocol_version: "1.1" }
827
831
  };
832
+ var NULL_SINCE = {
833
+ "RelayDeviceStatusEvent.since_ms": { since: "1.1", olderPeersGet: 0 }
834
+ };
835
+ function statusForPeer(status, version) {
836
+ const rule = NULL_SINCE["RelayDeviceStatusEvent.since_ms"];
837
+ return status.since_ms === null && !knows(version, rule.since) ? { ...status, since_ms: rule.olderPeersGet } : status;
838
+ }
839
+ function versionSubprotocol(version) {
840
+ return `matrx.v${version}`;
841
+ }
842
+ function announcedVersion(offered) {
843
+ let best = `${PROTOCOL_MAJOR}.0`;
844
+ for (const p of offered) {
845
+ const m = /^matrx\.v(\d+\.\d+)$/.exec(p.trim());
846
+ if (m?.[1] && compareVersions(m[1], best) > 0 && m[1].startsWith(`${PROTOCOL_MAJOR}.`)) best = m[1];
847
+ }
848
+ return best;
849
+ }
828
850
  function compareVersions(a, b) {
829
851
  const [am = 0, an = 0] = a.split(".").map(Number);
830
852
  const [bm = 0, bn = 0] = b.split(".").map(Number);
@@ -862,10 +884,37 @@ function forPeer(op, part, value, version) {
862
884
  return data === body.data ? value : { ...body, data };
863
885
  }
864
886
  var VERSIONED_RESULT_OPS = [...RESULT_PATH.keys()];
887
+
888
+ // src/close-policy.ts
889
+ var CLOSE_RULES = {
890
+ [CloseCode.NORMAL]: { action: "reconnect", error: ["DEVICE_OFFLINE", "Connection closed"] },
891
+ [CloseCode.GOING_AWAY]: { action: "reconnect_now", error: ["DEVICE_OFFLINE", "Connection lost"] },
892
+ [CloseCode.ABNORMAL]: { action: "reconnect_now", error: ["DEVICE_OFFLINE", "Connection lost"] },
893
+ [CloseCode.DEVICE_RECONNECTED]: { action: "reconnect_now", error: ["DEVICE_OFFLINE", "Device reconnected"] },
894
+ [CloseCode.TRY_AGAIN_LATER]: { action: "reconnect", error: ["DEVICE_OFFLINE", "Relay busy; retrying"] },
895
+ [CloseCode.AUTH_INVALID]: { action: "reauth", outcome: "signed_out", error: ["AUTH_INVALID", "Sign-in was not accepted"] },
896
+ [CloseCode.AUTH_FORBIDDEN]: { action: "stop", outcome: "not_owned", error: ["AUTH_FORBIDDEN", "Not this device's owner"] },
897
+ [CloseCode.DEVICE_NOT_FOUND]: { action: "stop", outcome: "removed", error: ["NOT_FOUND", "Device not found"] },
898
+ [CloseCode.AUTH_EXPIRED]: { action: "reauth", outcome: "signed_out", error: ["AUTH_EXPIRED", "Sign-in expired"] },
899
+ [CloseCode.REPLACED]: { action: "stop", outcome: "replaced", error: ["CONFLICT", "Replaced by a newer connection"] },
900
+ [CloseCode.DEVICE_REVOKED]: { action: "stop", outcome: "revoked", error: ["AUTH_DEVICE_REVOKED", "This device was revoked"] },
901
+ // A malformed message, or a connection the relay lost track of: a fresh socket starts clean.
902
+ [CloseCode.PROTOCOL_ERROR]: { action: "reconnect", error: ["PROTOCOL_ERROR", "Connection reset by the relay"] },
903
+ [CloseCode.UPGRADE_REQUIRED]: { action: "stop", outcome: "upgrade_required", error: ["PROTOCOL_VERSION_UNSUPPORTED", "Protocol upgrade required"] }
904
+ };
905
+ var UNKNOWN = { action: "reconnect", error: ["DEVICE_OFFLINE", "Connection lost"] };
906
+ function closeRule(code) {
907
+ if (code === null || code === void 0) return CLOSE_RULES[CloseCode.ABNORMAL];
908
+ return CLOSE_RULES[code] ?? UNKNOWN;
909
+ }
910
+ function isTerminalClose(code) {
911
+ return closeRule(code).action === "stop";
912
+ }
865
913
  export {
866
914
  AbsPath,
867
915
  BEARER_PREFIX,
868
916
  BROADCAST_CID,
917
+ CLOSE_RULES,
869
918
  CancelMsg,
870
919
  ClientToCoreMsg,
871
920
  ClientType,
@@ -943,6 +992,7 @@ export {
943
992
  HelloMsg,
944
993
  Limits,
945
994
  NAMED_SCHEMAS,
995
+ NULL_SINCE,
946
996
  OPS,
947
997
  OpDescriptor,
948
998
  OsPermissionName,
@@ -989,7 +1039,9 @@ export {
989
1039
  SysinfoGetResult,
990
1040
  VERSIONED_RESULT_OPS,
991
1041
  Welcome,
1042
+ announcedVersion,
992
1043
  assertFrameHeader,
1044
+ closeRule,
993
1045
  compareVersions,
994
1046
  connectionEndFrame,
995
1047
  decodeFrame,
@@ -999,11 +1051,14 @@ export {
999
1051
  hasFlag,
1000
1052
  isConnectionEnd,
1001
1053
  isDesktopProtocolError,
1054
+ isTerminalClose,
1002
1055
  knows,
1003
1056
  negotiate,
1004
1057
  nonNegInt,
1005
1058
  readCid,
1006
1059
  stampCid,
1007
- u32
1060
+ statusForPeer,
1061
+ u32,
1062
+ versionSubprotocol
1008
1063
  };
1009
1064
  //# sourceMappingURL=index.js.map