@uxnan/shared 0.0.3-alpha.20260702 → 0.0.4-alpha.20260703

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 CHANGED
@@ -52,8 +52,9 @@ flowchart TB
52
52
  | JSON-RPC | envelope types + constructors (`makeRequest`, `makeNotification`, `makeResponse`, `makeErrorResponse`), error codes (`JsonRpcErrorCode` + Uxnan-specific `-32000..-32008`), `RpcError`, typed method registry (`JsonRpcMethodRegistry` + `METHOD_NAMES`), `isKnownMethod` |
53
53
  | Streaming | `StreamNotification` enum + param types (`TurnStartedParams`, `MessageDeltaParams`, `ThinkingDeltaParams`, `ContentBlockParams`, `TurnCompletedParams`, `TurnUsage`, `TurnErrorParams`, `TurnAbortedParams`, `ModelResolvedParams`) |
54
54
  | E2EE | handshake messages (`clientHello` / `serverHello` / `clientAuth` / `ready`), `buildHandshakeTranscript`, `SecureEnvelope`, `PairingPayload` v2 (`relay` optional + `hosts: string[]`) with `Base64(utf8(JSON))` QR encoding |
55
- | Models | thread / turn / message (with `MessageContent` polymorphic blocks), git, workspace (incl. `browseDirs` + `exists`), project, auth, session/trust, approval |
55
+ | Models | thread / turn / message (with `MessageContent` polymorphic blocks), git, workspace (incl. `browseDirs` + `exists`), project, auth, session/trust (`BridgeStatus` incl. `latestVersion?`/`updateAvailable?`), approval |
56
56
  | Agents | `IAgentAdapter` (with `respondApproval`, `listModels`, `nativeSessionId`, `SendTurnOptions { threadId, turnId, text, service?, effort?, options?, attachments?, cwd?, accessMode? }`), `AgentModel` (incl. `version?`, `isDefault?`, `options?`, `contextWindow?`, `isLatestAlias?`), `AgentCapabilities` (incl. `images`, `approvals`, `reportsContextUsage`), `AgentConfig` (cwd, agentId, model, plus optional `binaryPath`/`extraArgs`) |
57
+ | Version | `compareVersions` / `isNewerVersion` — dependency-free SemVer precedence (used by the bridge's npm update check) |
57
58
  | Validation | Ajv validators for requests, responses, envelopes, pairing payload, push payloads |
58
59
 
59
60
  ## Usage
@@ -14,6 +14,7 @@ export * from './e2ee/pairing-payload.js';
14
14
  export * from './agents/agent-capabilities.js';
15
15
  export * from './agents/agent-config.js';
16
16
  export * from './agents/agent-adapter.js';
17
+ export * from './version/compare.js';
17
18
  export * from './notifications/push-payload.js';
18
19
  export * from './models/thread.js';
19
20
  export * from './models/git.js';
package/dist/src/index.js CHANGED
@@ -17,6 +17,8 @@ export * from './e2ee/pairing-payload.js';
17
17
  export * from './agents/agent-capabilities.js';
18
18
  export * from './agents/agent-config.js';
19
19
  export * from './agents/agent-adapter.js';
20
+ // Version
21
+ export * from './version/compare.js';
20
22
  // Notifications
21
23
  export * from './notifications/push-payload.js';
22
24
  // Models
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,gBAAgB,CAAC;AAE/B,WAAW;AACX,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAE3C,OAAO;AACP,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAE1C,SAAS;AACT,cAAc,gCAAgC,CAAC;AAC/C,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC;AAE1C,gBAAgB;AAChB,cAAc,iCAAiC,CAAC;AAEhD,SAAS;AACT,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AAErC,aAAa;AACb,cAAc,0BAA0B,CAAC;AACzC,cAAc,qCAAqC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,gBAAgB,CAAC;AAE/B,WAAW;AACX,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,4BAA4B,CAAC;AAE3C,OAAO;AACP,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAE1C,SAAS;AACT,cAAc,gCAAgC,CAAC;AAC/C,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC;AAE1C,UAAU;AACV,cAAc,sBAAsB,CAAC;AAErC,gBAAgB;AAChB,cAAc,iCAAiC,CAAC;AAEhD,SAAS;AACT,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AAErC,aAAa;AACb,cAAc,0BAA0B,CAAC;AACzC,cAAc,qCAAqC,CAAC"}
@@ -25,4 +25,16 @@ export interface BridgeStatus {
25
25
  activeSessions: number;
26
26
  platform: NodeJS.Platform | string;
27
27
  uptimeMs: number;
28
+ /**
29
+ * Latest bridge version published to npm (dist-tag `alpha`), as discovered by
30
+ * the bridge's own background update check. Absent when the check hasn't run
31
+ * yet or couldn't reach the registry (offline) — never blocks status.
32
+ */
33
+ latestVersion?: string;
34
+ /**
35
+ * True when {@link latestVersion} is strictly newer than {@link version}
36
+ * (SemVer precedence). Lets the phone show a "bridge update available" hint
37
+ * without querying npm itself. Absent/false when unknown or up to date.
38
+ */
39
+ updateAvailable?: boolean;
28
40
  }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Semantic-version comparison shared across the ecosystem.
3
+ *
4
+ * Uxnan versions follow SemVer with a date-stamped prerelease, e.g.
5
+ * `0.0.3-alpha.20260702` (and, on mobile, an optional `+<build>` metadata
6
+ * suffix). This implements SemVer 2.0.0 precedence (§11) closely enough for
7
+ * those formats — enough for the bridge to decide "is the published version
8
+ * newer than mine?" without pulling in a `semver` dependency.
9
+ *
10
+ * Build metadata (`+...`) is ignored for precedence, per the spec.
11
+ */
12
+ /**
13
+ * Compare two SemVer strings. Returns `-1` if `a < b`, `1` if `a > b`, `0` if
14
+ * they are precedence-equal. Unparseable inputs sort as *lower* than any
15
+ * parseable version (and equal to each other), so a garbage/absent version
16
+ * never masquerades as "newer".
17
+ */
18
+ export declare function compareVersions(a: string, b: string): number;
19
+ /**
20
+ * True when `candidate` is a strictly newer version than `current`. Used to
21
+ * decide whether to announce an available update. A candidate that is absent or
22
+ * unparseable is never treated as newer.
23
+ */
24
+ export declare function isNewerVersion(candidate: string | undefined | null, current: string): boolean;
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Semantic-version comparison shared across the ecosystem.
3
+ *
4
+ * Uxnan versions follow SemVer with a date-stamped prerelease, e.g.
5
+ * `0.0.3-alpha.20260702` (and, on mobile, an optional `+<build>` metadata
6
+ * suffix). This implements SemVer 2.0.0 precedence (§11) closely enough for
7
+ * those formats — enough for the bridge to decide "is the published version
8
+ * newer than mine?" without pulling in a `semver` dependency.
9
+ *
10
+ * Build metadata (`+...`) is ignored for precedence, per the spec.
11
+ */
12
+ /** Parse `MAJOR.MINOR.PATCH[-prerelease][+build]`, or `null` if unparseable. */
13
+ function parseVersion(version) {
14
+ const trimmed = version.trim();
15
+ if (!trimmed)
16
+ return null;
17
+ // Strip build metadata (everything from the first `+`), which never affects
18
+ // precedence.
19
+ const noBuild = trimmed.split('+', 1)[0];
20
+ const dashIndex = noBuild.indexOf('-');
21
+ const core = dashIndex === -1 ? noBuild : noBuild.slice(0, dashIndex);
22
+ const prereleaseRaw = dashIndex === -1 ? '' : noBuild.slice(dashIndex + 1);
23
+ const coreParts = core.split('.');
24
+ if (coreParts.length !== 3)
25
+ return null;
26
+ const major = Number(coreParts[0]);
27
+ const minor = Number(coreParts[1]);
28
+ const patch = Number(coreParts[2]);
29
+ if (!Number.isInteger(major) ||
30
+ !Number.isInteger(minor) ||
31
+ !Number.isInteger(patch) ||
32
+ major < 0 ||
33
+ minor < 0 ||
34
+ patch < 0) {
35
+ return null;
36
+ }
37
+ const prerelease = prereleaseRaw.length > 0 ? prereleaseRaw.split('.') : [];
38
+ return { major, minor, patch, prerelease };
39
+ }
40
+ /** Numeric identifiers are all-digits (SemVer §9). */
41
+ function isNumericIdentifier(id) {
42
+ return id.length > 0 && /^[0-9]+$/.test(id);
43
+ }
44
+ /** Compare two prerelease identifier lists per SemVer §11. */
45
+ function comparePrerelease(a, b) {
46
+ // A release with no prerelease outranks one that has a prerelease.
47
+ if (a.length === 0 && b.length === 0)
48
+ return 0;
49
+ if (a.length === 0)
50
+ return 1; // `a` is stable, `b` is prerelease → a > b
51
+ if (b.length === 0)
52
+ return -1;
53
+ const len = Math.min(a.length, b.length);
54
+ for (let i = 0; i < len; i++) {
55
+ const idA = a[i];
56
+ const idB = b[i];
57
+ if (idA === idB)
58
+ continue;
59
+ const numA = isNumericIdentifier(idA);
60
+ const numB = isNumericIdentifier(idB);
61
+ if (numA && numB) {
62
+ const diff = Number(idA) - Number(idB);
63
+ if (diff !== 0)
64
+ return diff < 0 ? -1 : 1;
65
+ }
66
+ else if (numA) {
67
+ return -1; // numeric identifiers have lower precedence than alphanumeric
68
+ }
69
+ else if (numB) {
70
+ return 1;
71
+ }
72
+ else {
73
+ return idA < idB ? -1 : 1; // lexical ASCII order
74
+ }
75
+ }
76
+ // All shared identifiers equal → the longer set has higher precedence.
77
+ if (a.length === b.length)
78
+ return 0;
79
+ return a.length < b.length ? -1 : 1;
80
+ }
81
+ /**
82
+ * Compare two SemVer strings. Returns `-1` if `a < b`, `1` if `a > b`, `0` if
83
+ * they are precedence-equal. Unparseable inputs sort as *lower* than any
84
+ * parseable version (and equal to each other), so a garbage/absent version
85
+ * never masquerades as "newer".
86
+ */
87
+ export function compareVersions(a, b) {
88
+ const pa = parseVersion(a);
89
+ const pb = parseVersion(b);
90
+ if (!pa && !pb)
91
+ return 0;
92
+ if (!pa)
93
+ return -1;
94
+ if (!pb)
95
+ return 1;
96
+ if (pa.major !== pb.major)
97
+ return pa.major < pb.major ? -1 : 1;
98
+ if (pa.minor !== pb.minor)
99
+ return pa.minor < pb.minor ? -1 : 1;
100
+ if (pa.patch !== pb.patch)
101
+ return pa.patch < pb.patch ? -1 : 1;
102
+ return comparePrerelease(pa.prerelease, pb.prerelease);
103
+ }
104
+ /**
105
+ * True when `candidate` is a strictly newer version than `current`. Used to
106
+ * decide whether to announce an available update. A candidate that is absent or
107
+ * unparseable is never treated as newer.
108
+ */
109
+ export function isNewerVersion(candidate, current) {
110
+ if (!candidate)
111
+ return false;
112
+ if (parseVersion(candidate) === null)
113
+ return false;
114
+ return compareVersions(candidate, current) > 0;
115
+ }
116
+ //# sourceMappingURL=compare.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare.js","sourceRoot":"","sources":["../../../src/version/compare.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uxnan/shared",
3
- "version": "0.0.3-alpha.20260702",
3
+ "version": "0.0.4-alpha.20260703",
4
4
  "description": "Shared JSON-RPC and E2EE contracts for the Uxnan ecosystem (bridge, relay, mobile).",
5
5
  "license": "MPL-2.0",
6
6
  "author": "Luis Donaldo Gamas Vazquez",