@ai-matrx/desktop-protocol 0.6.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/react.d.cts CHANGED
@@ -23,6 +23,23 @@ interface ErrorData {
23
23
  } | undefined;
24
24
  }
25
25
 
26
+ /**
27
+ * What a connecting side does after each WebSocket close — the ONE table every client reads (the
28
+ * package client, the desktop's relay transport, any other dialer). Never keep a local list of
29
+ * "terminal" codes: a code added to CloseCode without a rule here fails to compile.
30
+ *
31
+ * reconnect_now the far side went away on purpose or the socket died; dial again at once if the
32
+ * connection had opened, with backoff otherwise (a dead network never spins).
33
+ * reconnect transient refusal; dial again with backoff.
34
+ * reauth the token was refused; get a FRESH token and dial once more. A second refusal in
35
+ * a row (no successful open between) is terminal with outcome "signed_out".
36
+ * stop retrying cannot help: stop dialing until something changes (a new sign-in, a
37
+ * new device, an update) and show the outcome.
38
+ */
39
+
40
+ /** The one state a person is shown when dialing stops. */
41
+ type CloseOutcome = "signed_out" | "not_owned" | "removed" | "revoked" | "replaced" | "upgrade_required";
42
+
26
43
  /**
27
44
  * The one error type every package entry throws. It carries the wire ErrorCode (SPEC §5), so a
28
45
  * caller branches on `code`/`retryable`/`data.reason` and never parses a message. Zod-free on
@@ -839,6 +856,8 @@ interface DesktopClientState {
839
856
  retryInMs: number | null;
840
857
  lastError: DesktopProtocolError | null;
841
858
  lastCloseCode: number | null;
859
+ /** Why dialing stopped, when the far side refused us for good (CLOSE_RULES); null otherwise. */
860
+ outcome: CloseOutcome | null;
842
861
  }
843
862
  interface RequestOptions {
844
863
  signal?: AbortSignal;
package/dist/react.d.ts CHANGED
@@ -23,6 +23,23 @@ interface ErrorData {
23
23
  } | undefined;
24
24
  }
25
25
 
26
+ /**
27
+ * What a connecting side does after each WebSocket close — the ONE table every client reads (the
28
+ * package client, the desktop's relay transport, any other dialer). Never keep a local list of
29
+ * "terminal" codes: a code added to CloseCode without a rule here fails to compile.
30
+ *
31
+ * reconnect_now the far side went away on purpose or the socket died; dial again at once if the
32
+ * connection had opened, with backoff otherwise (a dead network never spins).
33
+ * reconnect transient refusal; dial again with backoff.
34
+ * reauth the token was refused; get a FRESH token and dial once more. A second refusal in
35
+ * a row (no successful open between) is terminal with outcome "signed_out".
36
+ * stop retrying cannot help: stop dialing until something changes (a new sign-in, a
37
+ * new device, an update) and show the outcome.
38
+ */
39
+
40
+ /** The one state a person is shown when dialing stops. */
41
+ type CloseOutcome = "signed_out" | "not_owned" | "removed" | "revoked" | "replaced" | "upgrade_required";
42
+
26
43
  /**
27
44
  * The one error type every package entry throws. It carries the wire ErrorCode (SPEC §5), so a
28
45
  * caller branches on `code`/`retryable`/`data.reason` and never parses a message. Zod-free on
@@ -839,6 +856,8 @@ interface DesktopClientState {
839
856
  retryInMs: number | null;
840
857
  lastError: DesktopProtocolError | null;
841
858
  lastCloseCode: number | null;
859
+ /** Why dialing stopped, when the far side refused us for good (CLOSE_RULES); null otherwise. */
860
+ outcome: CloseOutcome | null;
842
861
  }
843
862
  interface RequestOptions {
844
863
  signal?: AbortSignal;
@@ -22,6 +22,96 @@ interface ErrorData {
22
22
  } | undefined;
23
23
  }
24
24
 
25
+ /**
26
+ * What a connecting side does after each WebSocket close — the ONE table every client reads (the
27
+ * package client, the desktop's relay transport, any other dialer). Never keep a local list of
28
+ * "terminal" codes: a code added to CloseCode without a rule here fails to compile.
29
+ *
30
+ * reconnect_now the far side went away on purpose or the socket died; dial again at once if the
31
+ * connection had opened, with backoff otherwise (a dead network never spins).
32
+ * reconnect transient refusal; dial again with backoff.
33
+ * reauth the token was refused; get a FRESH token and dial once more. A second refusal in
34
+ * a row (no successful open between) is terminal with outcome "signed_out".
35
+ * stop retrying cannot help: stop dialing until something changes (a new sign-in, a
36
+ * new device, an update) and show the outcome.
37
+ */
38
+
39
+ type CloseAction = "reconnect_now" | "reconnect" | "reauth" | "stop";
40
+ /** The one state a person is shown when dialing stops. */
41
+ type CloseOutcome = "signed_out" | "not_owned" | "removed" | "revoked" | "replaced" | "upgrade_required";
42
+ interface CloseRule {
43
+ readonly action: CloseAction;
44
+ /** Set for `stop` and `reauth` (the outcome when the fresh token is refused too). */
45
+ readonly outcome?: CloseOutcome;
46
+ /** The error a caller's pending work is failed with. */
47
+ readonly error: readonly [ErrorCodeName, string];
48
+ }
49
+ declare const CLOSE_RULES: {
50
+ readonly 1000: {
51
+ readonly action: "reconnect";
52
+ readonly error: readonly ["DEVICE_OFFLINE", "Connection closed"];
53
+ };
54
+ readonly 1001: {
55
+ readonly action: "reconnect_now";
56
+ readonly error: readonly ["DEVICE_OFFLINE", "Connection lost"];
57
+ };
58
+ readonly 1006: {
59
+ readonly action: "reconnect_now";
60
+ readonly error: readonly ["DEVICE_OFFLINE", "Connection lost"];
61
+ };
62
+ readonly 1012: {
63
+ readonly action: "reconnect_now";
64
+ readonly error: readonly ["DEVICE_OFFLINE", "Device reconnected"];
65
+ };
66
+ readonly 1013: {
67
+ readonly action: "reconnect";
68
+ readonly error: readonly ["DEVICE_OFFLINE", "Relay busy; retrying"];
69
+ };
70
+ readonly 4001: {
71
+ readonly action: "reauth";
72
+ readonly outcome: "signed_out";
73
+ readonly error: readonly ["AUTH_INVALID", "Sign-in was not accepted"];
74
+ };
75
+ readonly 4003: {
76
+ readonly action: "stop";
77
+ readonly outcome: "not_owned";
78
+ readonly error: readonly ["AUTH_FORBIDDEN", "Not this device's owner"];
79
+ };
80
+ readonly 4004: {
81
+ readonly action: "stop";
82
+ readonly outcome: "removed";
83
+ readonly error: readonly ["NOT_FOUND", "Device not found"];
84
+ };
85
+ readonly 4008: {
86
+ readonly action: "reauth";
87
+ readonly outcome: "signed_out";
88
+ readonly error: readonly ["AUTH_EXPIRED", "Sign-in expired"];
89
+ };
90
+ readonly 4009: {
91
+ readonly action: "stop";
92
+ readonly outcome: "replaced";
93
+ readonly error: readonly ["CONFLICT", "Replaced by a newer connection"];
94
+ };
95
+ readonly 4010: {
96
+ readonly action: "stop";
97
+ readonly outcome: "revoked";
98
+ readonly error: readonly ["AUTH_DEVICE_REVOKED", "This device was revoked"];
99
+ };
100
+ readonly 4400: {
101
+ readonly action: "reconnect";
102
+ readonly error: readonly ["PROTOCOL_ERROR", "Connection reset by the relay"];
103
+ };
104
+ readonly 4426: {
105
+ readonly action: "stop";
106
+ readonly outcome: "upgrade_required";
107
+ readonly error: readonly ["PROTOCOL_VERSION_UNSUPPORTED", "Protocol upgrade required"];
108
+ };
109
+ };
110
+ /** The rule for any close code; one this table does not know (or null: no close frame) reconnects with backoff. */
111
+ declare function closeRule(code: number | null | undefined): CloseRule;
112
+ /** True when dialing must stop after this close (no retry will help). */
113
+ declare function isTerminalClose(code: number | null | undefined): boolean;
114
+
25
115
  /**
26
116
  * The one error type every package entry throws. It carries the wire ErrorCode (SPEC §5), so a
27
117
  * caller branches on `code`/`retryable`/`data.reason` and never parses a message. Zod-free on
@@ -2445,4 +2535,4 @@ declare const NAMED_SCHEMAS: {
2445
2535
  };
2446
2536
  type NamedSchemaId = keyof typeof NAMED_SCHEMAS;
2447
2537
 
2448
- export { ResponseMsg as A, BEARER_PREFIX as B, ClientType as C, DesktopProtocolError as D, EndReason as E, FsPatchEditFailure as F, SUBPROTOCOL as G, HelloMsg as H, StreamMsg as I, Limits as L, NAMED_SCHEMAS as N, type OpName as O, PING_TEXT as P, RelayMsg as R, StreamMeta as S, Welcome as W, type OpParams as a, type OpResult as b, OPS as c, EVENTS as d, CancelMsg as e, ClientToCoreMsg as f, CloseCode as g, CloseCodeValue as h, isDesktopProtocolError as i, CoreToClientMsg as j, CreditMsg as k, EndMsg as l, ErrorCode as m, type ErrorCodeName as n, type ErrorData as o, ErrorMsg as p, ErrorReason as q, type ErrorReasonName as r, EventMsg as s, type EventName as t, type NamedSchemaId as u, OpDescriptor as v, type OpSpec as w, PONG_TEXT as x, ProtocolErrorBody as y, RequestMsg as z };
2538
+ export { type OpSpec as A, BEARER_PREFIX as B, type CloseOutcome as C, DesktopProtocolError as D, EndReason as E, FsPatchEditFailure as F, PONG_TEXT as G, HelloMsg as H, ProtocolErrorBody as I, RequestMsg as J, ResponseMsg as K, Limits as L, SUBPROTOCOL as M, NAMED_SCHEMAS as N, type OpName as O, PING_TEXT as P, StreamMsg as Q, RelayMsg as R, StreamMeta as S, closeRule as T, isTerminalClose as U, Welcome as W, type OpParams as a, type OpResult as b, OPS as c, EVENTS as d, ClientType as e, CLOSE_RULES as f, CancelMsg as g, ClientToCoreMsg as h, isDesktopProtocolError as i, type CloseAction as j, CloseCode as k, CloseCodeValue as l, type CloseRule as m, CoreToClientMsg as n, CreditMsg as o, EndMsg as p, ErrorCode as q, type ErrorCodeName as r, type ErrorData as s, ErrorMsg as t, ErrorReason as u, type ErrorReasonName as v, EventMsg as w, type EventName as x, type NamedSchemaId as y, OpDescriptor as z };
@@ -22,6 +22,96 @@ interface ErrorData {
22
22
  } | undefined;
23
23
  }
24
24
 
25
+ /**
26
+ * What a connecting side does after each WebSocket close — the ONE table every client reads (the
27
+ * package client, the desktop's relay transport, any other dialer). Never keep a local list of
28
+ * "terminal" codes: a code added to CloseCode without a rule here fails to compile.
29
+ *
30
+ * reconnect_now the far side went away on purpose or the socket died; dial again at once if the
31
+ * connection had opened, with backoff otherwise (a dead network never spins).
32
+ * reconnect transient refusal; dial again with backoff.
33
+ * reauth the token was refused; get a FRESH token and dial once more. A second refusal in
34
+ * a row (no successful open between) is terminal with outcome "signed_out".
35
+ * stop retrying cannot help: stop dialing until something changes (a new sign-in, a
36
+ * new device, an update) and show the outcome.
37
+ */
38
+
39
+ type CloseAction = "reconnect_now" | "reconnect" | "reauth" | "stop";
40
+ /** The one state a person is shown when dialing stops. */
41
+ type CloseOutcome = "signed_out" | "not_owned" | "removed" | "revoked" | "replaced" | "upgrade_required";
42
+ interface CloseRule {
43
+ readonly action: CloseAction;
44
+ /** Set for `stop` and `reauth` (the outcome when the fresh token is refused too). */
45
+ readonly outcome?: CloseOutcome;
46
+ /** The error a caller's pending work is failed with. */
47
+ readonly error: readonly [ErrorCodeName, string];
48
+ }
49
+ declare const CLOSE_RULES: {
50
+ readonly 1000: {
51
+ readonly action: "reconnect";
52
+ readonly error: readonly ["DEVICE_OFFLINE", "Connection closed"];
53
+ };
54
+ readonly 1001: {
55
+ readonly action: "reconnect_now";
56
+ readonly error: readonly ["DEVICE_OFFLINE", "Connection lost"];
57
+ };
58
+ readonly 1006: {
59
+ readonly action: "reconnect_now";
60
+ readonly error: readonly ["DEVICE_OFFLINE", "Connection lost"];
61
+ };
62
+ readonly 1012: {
63
+ readonly action: "reconnect_now";
64
+ readonly error: readonly ["DEVICE_OFFLINE", "Device reconnected"];
65
+ };
66
+ readonly 1013: {
67
+ readonly action: "reconnect";
68
+ readonly error: readonly ["DEVICE_OFFLINE", "Relay busy; retrying"];
69
+ };
70
+ readonly 4001: {
71
+ readonly action: "reauth";
72
+ readonly outcome: "signed_out";
73
+ readonly error: readonly ["AUTH_INVALID", "Sign-in was not accepted"];
74
+ };
75
+ readonly 4003: {
76
+ readonly action: "stop";
77
+ readonly outcome: "not_owned";
78
+ readonly error: readonly ["AUTH_FORBIDDEN", "Not this device's owner"];
79
+ };
80
+ readonly 4004: {
81
+ readonly action: "stop";
82
+ readonly outcome: "removed";
83
+ readonly error: readonly ["NOT_FOUND", "Device not found"];
84
+ };
85
+ readonly 4008: {
86
+ readonly action: "reauth";
87
+ readonly outcome: "signed_out";
88
+ readonly error: readonly ["AUTH_EXPIRED", "Sign-in expired"];
89
+ };
90
+ readonly 4009: {
91
+ readonly action: "stop";
92
+ readonly outcome: "replaced";
93
+ readonly error: readonly ["CONFLICT", "Replaced by a newer connection"];
94
+ };
95
+ readonly 4010: {
96
+ readonly action: "stop";
97
+ readonly outcome: "revoked";
98
+ readonly error: readonly ["AUTH_DEVICE_REVOKED", "This device was revoked"];
99
+ };
100
+ readonly 4400: {
101
+ readonly action: "reconnect";
102
+ readonly error: readonly ["PROTOCOL_ERROR", "Connection reset by the relay"];
103
+ };
104
+ readonly 4426: {
105
+ readonly action: "stop";
106
+ readonly outcome: "upgrade_required";
107
+ readonly error: readonly ["PROTOCOL_VERSION_UNSUPPORTED", "Protocol upgrade required"];
108
+ };
109
+ };
110
+ /** The rule for any close code; one this table does not know (or null: no close frame) reconnects with backoff. */
111
+ declare function closeRule(code: number | null | undefined): CloseRule;
112
+ /** True when dialing must stop after this close (no retry will help). */
113
+ declare function isTerminalClose(code: number | null | undefined): boolean;
114
+
25
115
  /**
26
116
  * The one error type every package entry throws. It carries the wire ErrorCode (SPEC §5), so a
27
117
  * caller branches on `code`/`retryable`/`data.reason` and never parses a message. Zod-free on
@@ -2445,4 +2535,4 @@ declare const NAMED_SCHEMAS: {
2445
2535
  };
2446
2536
  type NamedSchemaId = keyof typeof NAMED_SCHEMAS;
2447
2537
 
2448
- export { ResponseMsg as A, BEARER_PREFIX as B, ClientType as C, DesktopProtocolError as D, EndReason as E, FsPatchEditFailure as F, SUBPROTOCOL as G, HelloMsg as H, StreamMsg as I, Limits as L, NAMED_SCHEMAS as N, type OpName as O, PING_TEXT as P, RelayMsg as R, StreamMeta as S, Welcome as W, type OpParams as a, type OpResult as b, OPS as c, EVENTS as d, CancelMsg as e, ClientToCoreMsg as f, CloseCode as g, CloseCodeValue as h, isDesktopProtocolError as i, CoreToClientMsg as j, CreditMsg as k, EndMsg as l, ErrorCode as m, type ErrorCodeName as n, type ErrorData as o, ErrorMsg as p, ErrorReason as q, type ErrorReasonName as r, EventMsg as s, type EventName as t, type NamedSchemaId as u, OpDescriptor as v, type OpSpec as w, PONG_TEXT as x, ProtocolErrorBody as y, RequestMsg as z };
2538
+ export { type OpSpec as A, BEARER_PREFIX as B, type CloseOutcome as C, DesktopProtocolError as D, EndReason as E, FsPatchEditFailure as F, PONG_TEXT as G, HelloMsg as H, ProtocolErrorBody as I, RequestMsg as J, ResponseMsg as K, Limits as L, SUBPROTOCOL as M, NAMED_SCHEMAS as N, type OpName as O, PING_TEXT as P, StreamMsg as Q, RelayMsg as R, StreamMeta as S, closeRule as T, isTerminalClose as U, Welcome as W, type OpParams as a, type OpResult as b, OPS as c, EVENTS as d, ClientType as e, CLOSE_RULES as f, CancelMsg as g, ClientToCoreMsg as h, isDesktopProtocolError as i, type CloseAction as j, CloseCode as k, CloseCodeValue as l, type CloseRule as m, CoreToClientMsg as n, CreditMsg as o, EndMsg as p, ErrorCode as q, type ErrorCodeName as r, type ErrorData as s, ErrorMsg as t, ErrorReason as u, type ErrorReasonName as v, EventMsg as w, type EventName as x, type NamedSchemaId as y, OpDescriptor as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-matrx/desktop-protocol",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "The one wire contract between Matrx 2 (the desktop app) and every client that drives it — phone, web app, extension, server: zod schemas for the envelope and every cap.op, the 16-byte binary frame codec, a reconnecting request/stream/credit/reattach client, React hooks, and a generated JSON Schema + Pydantic twin that CI keeps byte-identical.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",