@ai-matrx/desktop-protocol 0.4.0 → 0.6.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.cjs CHANGED
@@ -59,6 +59,7 @@ __export(src_exports, {
59
59
  ExecRunParams: () => ExecRunParams,
60
60
  ExecRunResult: () => ExecRunResult,
61
61
  ExecTitleEvent: () => ExecTitleEvent,
62
+ FIELDS_SINCE: () => FIELDS_SINCE,
62
63
  FRAME_HEADER_BYTES: () => FRAME_HEADER_BYTES,
63
64
  FRAME_STRUCT_FORMAT: () => FRAME_STRUCT_FORMAT,
64
65
  FRAME_VERSION: () => FRAME_VERSION,
@@ -99,6 +100,7 @@ __export(src_exports, {
99
100
  HelloMsg: () => HelloMsg,
100
101
  Limits: () => Limits,
101
102
  NAMED_SCHEMAS: () => NAMED_SCHEMAS,
103
+ NULL_SINCE: () => NULL_SINCE,
102
104
  OPS: () => OPS,
103
105
  OpDescriptor: () => OpDescriptor,
104
106
  OsPermissionName: () => OsPermissionName,
@@ -112,6 +114,7 @@ __export(src_exports, {
112
114
  PtyInfo: () => PtyInfo,
113
115
  RELAY_CALL_HELLO_ID: () => RELAY_CALL_HELLO_ID,
114
116
  RELAY_CALL_REQUEST_ID: () => RELAY_CALL_REQUEST_ID,
117
+ RELAY_CALL_VERSION_HEADER: () => RELAY_CALL_VERSION_HEADER,
115
118
  RelayAuthExpiringEvent: () => RelayAuthExpiringEvent,
116
119
  RelayCallEnvelope: () => RelayCallEnvelope,
117
120
  RelayCallHello: () => RelayCallHello,
@@ -142,26 +145,34 @@ __export(src_exports, {
142
145
  StreamMsg: () => StreamMsg,
143
146
  SysinfoGetParams: () => SysinfoGetParams,
144
147
  SysinfoGetResult: () => SysinfoGetResult,
148
+ VERSIONED_RESULT_OPS: () => VERSIONED_RESULT_OPS,
145
149
  Welcome: () => Welcome,
150
+ announcedVersion: () => announcedVersion,
146
151
  assertFrameHeader: () => assertFrameHeader,
152
+ compareVersions: () => compareVersions,
147
153
  connectionEndFrame: () => connectionEndFrame,
148
154
  decodeFrame: () => decodeFrame,
149
155
  encodeFrame: () => encodeFrame,
150
156
  epochMs: () => epochMs,
157
+ forPeer: () => forPeer,
151
158
  hasFlag: () => hasFlag,
152
159
  isConnectionEnd: () => isConnectionEnd,
153
160
  isDesktopProtocolError: () => isDesktopProtocolError,
161
+ knows: () => knows,
162
+ negotiate: () => negotiate,
154
163
  nonNegInt: () => nonNegInt,
155
164
  readCid: () => readCid,
156
165
  stampCid: () => stampCid,
157
- u32: () => u32
166
+ statusForPeer: () => statusForPeer,
167
+ u32: () => u32,
168
+ versionSubprotocol: () => versionSubprotocol
158
169
  });
159
170
  module.exports = __toCommonJS(src_exports);
160
171
 
161
172
  // src/schema/primitives.ts
162
173
  var import_zod = require("zod");
163
174
  var PROTOCOL_MAJOR = 1;
164
- var PROTOCOL_MINOR = 0;
175
+ var PROTOCOL_MINOR = 1;
165
176
  var PROTOCOL_VERSION = `${PROTOCOL_MAJOR}.${PROTOCOL_MINOR}`;
166
177
  var ProtocolVersion = import_zod.z.string().regex(/^[1-9][0-9]{0,2}\.[0-9]{1,3}$/);
167
178
  var RequestId = import_zod.z.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/);
@@ -655,8 +666,10 @@ var FsPatchResult = import_zod6.z.strictObject({
655
666
  applied: nonNegInt,
656
667
  size: nonNegInt,
657
668
  mtime_ms: epochMs,
658
- edits_applied: import_zod6.z.array(FsPatchEditApplied).max(256),
659
- edits_failed: import_zod6.z.array(FsPatchEditFailure).max(256)
669
+ /** Since 1.1 (FIELDS_SINCE): a 1.0 app sends only `applied`. Always sent to a ≥1.1 peer. */
670
+ edits_applied: import_zod6.z.array(FsPatchEditApplied).max(256).optional(),
671
+ /** Since 1.1 (FIELDS_SINCE). */
672
+ edits_failed: import_zod6.z.array(FsPatchEditFailure).max(256).optional()
660
673
  });
661
674
  var FsSearchPathsParams = import_zod6.z.strictObject({
662
675
  pattern: import_zod6.z.string().min(1).max(512),
@@ -796,7 +809,11 @@ var SessionControlChangedEvent = import_zod8.z.strictObject({ controller_client_
796
809
  var import_zod9 = require("zod");
797
810
  var RelayDeviceStatusEvent = import_zod9.z.strictObject({
798
811
  online: import_zod9.z.boolean(),
799
- since_ms: epochMs,
812
+ /**
813
+ * When the device last went online/offline; null = it has never connected (since 1.1 —
814
+ * NULL_SINCE: a 1.0 reader is sent 0, its old meaning).
815
+ */
816
+ since_ms: epochMs.nullable(),
800
817
  app_version: import_zod9.z.string().max(32).nullable(),
801
818
  protocol_version: ProtocolVersion.nullable()
802
819
  });
@@ -807,9 +824,20 @@ var RelayCallRequest = import_zod9.z.strictObject({
807
824
  params: import_zod9.z.unknown(),
808
825
  timeout_ms: import_zod9.z.int().min(100).max(37e5).default(7e4)
809
826
  });
827
+ var RELAY_CALL_VERSION_HEADER = "x-matrx-protocol-version";
810
828
  var RelayCallResponse = import_zod9.z.discriminatedUnion("ok", [
811
- import_zod9.z.strictObject({ ok: import_zod9.z.literal(true), result: import_zod9.z.unknown() }),
812
- import_zod9.z.strictObject({ ok: import_zod9.z.literal(false), error: ProtocolErrorBody })
829
+ import_zod9.z.strictObject({
830
+ ok: import_zod9.z.literal(true),
831
+ result: import_zod9.z.unknown(),
832
+ /** Since 1.1: the version the device negotiated for this call (its welcome). */
833
+ protocol_version: ProtocolVersion.optional()
834
+ }),
835
+ import_zod9.z.strictObject({
836
+ ok: import_zod9.z.literal(false),
837
+ error: ProtocolErrorBody,
838
+ /** Since 1.1, as above (absent when the device never answered hello). */
839
+ protocol_version: ProtocolVersion.optional()
840
+ })
813
841
  ]);
814
842
  var RELAY_CALL_HELLO_ID = "hello";
815
843
  var RELAY_CALL_REQUEST_ID = "call";
@@ -964,4 +992,67 @@ var NAMED_SCHEMAS = {
964
992
  RelayHopConnectionEnd,
965
993
  CloseCodeValue
966
994
  };
995
+
996
+ // src/versioning.ts
997
+ var FIELDS_SINCE = {
998
+ FsPatchResult: { edits_applied: "1.1", edits_failed: "1.1" },
999
+ "ProtocolErrorBody.data": { edits_failed: "1.1" },
1000
+ "RelayCallResponse|0": { protocol_version: "1.1" },
1001
+ "RelayCallResponse|1": { protocol_version: "1.1" }
1002
+ };
1003
+ var NULL_SINCE = {
1004
+ "RelayDeviceStatusEvent.since_ms": { since: "1.1", olderPeersGet: 0 }
1005
+ };
1006
+ function statusForPeer(status, version) {
1007
+ const rule = NULL_SINCE["RelayDeviceStatusEvent.since_ms"];
1008
+ return status.since_ms === null && !knows(version, rule.since) ? { ...status, since_ms: rule.olderPeersGet } : status;
1009
+ }
1010
+ function versionSubprotocol(version) {
1011
+ return `matrx.v${version}`;
1012
+ }
1013
+ function announcedVersion(offered) {
1014
+ let best = `${PROTOCOL_MAJOR}.0`;
1015
+ for (const p of offered) {
1016
+ const m = /^matrx\.v(\d+\.\d+)$/.exec(p.trim());
1017
+ if (m?.[1] && compareVersions(m[1], best) > 0 && m[1].startsWith(`${PROTOCOL_MAJOR}.`)) best = m[1];
1018
+ }
1019
+ return best;
1020
+ }
1021
+ function compareVersions(a, b) {
1022
+ const [am = 0, an = 0] = a.split(".").map(Number);
1023
+ const [bm = 0, bn = 0] = b.split(".").map(Number);
1024
+ return am - bm || an - bn;
1025
+ }
1026
+ function knows(version, since) {
1027
+ return compareVersions(version, since) >= 0;
1028
+ }
1029
+ function negotiate(peerVersion) {
1030
+ const [major = 0, minor = 0] = peerVersion.split(".").map(Number);
1031
+ if (major !== PROTOCOL_MAJOR) return `${PROTOCOL_MAJOR}.0`;
1032
+ return `${PROTOCOL_MAJOR}.${Math.min(minor, PROTOCOL_MINOR)}`;
1033
+ }
1034
+ function strip(value, fields, version) {
1035
+ if (!fields || value === null || typeof value !== "object" || Array.isArray(value)) return value;
1036
+ let out = null;
1037
+ for (const [field, since] of Object.entries(fields)) {
1038
+ if (field in value && !knows(version, since)) {
1039
+ out ??= { ...value };
1040
+ delete out[field];
1041
+ }
1042
+ }
1043
+ return out ?? value;
1044
+ }
1045
+ var RESULT_PATH = /* @__PURE__ */ new Map([["fs.patch", "FsPatchResult"]]);
1046
+ function forPeer(op, part, value, version) {
1047
+ if (part === "result") {
1048
+ const path = op ? RESULT_PATH.get(op) : void 0;
1049
+ return path ? strip(value, FIELDS_SINCE[path], version) : value;
1050
+ }
1051
+ if (value === null || typeof value !== "object") return value;
1052
+ const body = value;
1053
+ if (body.data === void 0) return value;
1054
+ const data = strip(body.data, FIELDS_SINCE["ProtocolErrorBody.data"], version);
1055
+ return data === body.data ? value : { ...body, data };
1056
+ }
1057
+ var VERSIONED_RESULT_OPS = [...RESULT_PATH.keys()];
967
1058
  //# sourceMappingURL=index.cjs.map