@uxnan/shared 0.0.17-alpha.20260926 → 0.0.19-alpha.20260926
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 +2 -2
- package/dist/src/agents/agent-adapter.d.ts +2 -1
- package/dist/src/agents/agent-capabilities.d.ts +2 -1
- package/dist/src/jsonrpc/method-registry.d.ts +1 -1
- package/dist/src/jsonrpc/method-registry.js +1 -0
- package/dist/src/jsonrpc/method-registry.js.map +1 -1
- package/dist/src/jsonrpc/methods.d.ts +5 -12
- package/dist/src/jsonrpc/notifications.d.ts +11 -22
- package/dist/src/jsonrpc/notifications.js +6 -5
- package/dist/src/jsonrpc/notifications.js.map +1 -1
- package/dist/src/local-control/local-control.d.ts +13 -1
- package/dist/src/local-control/local-control.js +14 -0
- package/dist/src/local-control/local-control.js.map +1 -1
- package/dist/src/models/session.d.ts +66 -12
- package/dist/src/models/thread.d.ts +6 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|

|
|
4
4
|

|
|
5
5
|

|
|
6
|
-

|
|
7
7
|
|
|
8
8
|
Shared JSON-RPC and E2EE contracts for the [Uxnan](../README.md) ecosystem — the
|
|
9
9
|
single source of truth every component agrees on. Consumed as a local workspace
|
|
@@ -13,7 +13,7 @@ equivalents (see
|
|
|
13
13
|
[`architecture/02b-contracts-and-requirements.md`](../architecture/02b-contracts-and-requirements.md)
|
|
14
14
|
§1 for the canonical contract list).
|
|
15
15
|
|
|
16
|
-
> **Status:** implemented and stable — **
|
|
16
|
+
> **Status:** implemented and stable — **82 JSON-RPC methods** + **22 streaming
|
|
17
17
|
> notifications**, kept lock-step at build time with the `METHOD_NAMES` array and
|
|
18
18
|
> the `StreamNotification` enum (a compile-time assertion in
|
|
19
19
|
> `src/jsonrpc/method-registry.ts` fails the build on any drift). Changes are
|
|
@@ -124,7 +124,8 @@ export interface IAgentAdapter {
|
|
|
124
124
|
* `activeTurnId` is the bridge turn currently in flight on the thread, so the
|
|
125
125
|
* adapter can address the right run (and refuse if it has already moved on).
|
|
126
126
|
* `turnId` is the queued turn the text came from — it does NOT start a run of
|
|
127
|
-
* its own
|
|
127
|
+
* its own: the bridge makes it the turn that carries the rest of this run,
|
|
128
|
+
* and keeps naming the run by `activeTurnId` in every call to the adapter.
|
|
128
129
|
*
|
|
129
130
|
* Returns **true only when the agent actually took the message**. Return
|
|
130
131
|
* `false` (don't throw) for an ordinary "too late / not applicable" — the
|
|
@@ -56,7 +56,8 @@ export interface AgentCapabilities {
|
|
|
56
56
|
* making it wait for the next one — what a CLI does when you type while it
|
|
57
57
|
* works and it picks the message up at the next tool boundary. The bridge
|
|
58
58
|
* hands such a turn straight to the adapter (`IAgentAdapter.steerTurn`)
|
|
59
|
-
* rather than holding it
|
|
59
|
+
* rather than holding it; the turn that was answering ends there and the new
|
|
60
|
+
* one carries the rest of the agent's run (architecture/02a §5.8.13).
|
|
60
61
|
*
|
|
61
62
|
* Optional; absent/false means the agent has no input channel mid-turn (a
|
|
62
63
|
* one-shot CLI, or a protocol that serializes prompts per session), and its
|
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
* compile-time {@link JsonRpcMethodRegistry} via the assertion below.
|
|
4
4
|
*/
|
|
5
5
|
import type { JsonRpcMethodName } from './methods.js';
|
|
6
|
-
export declare const METHOD_NAMES: readonly ["thread/list", "thread/read", "thread/start", "thread/resume", "thread/fork", "thread/setModel", "thread/rename", "thread/setAccessMode", "thread/archive", "thread/unarchive", "thread/delete", "turn/list", "turn/read", "turn/send", "turn/cancel", "queue/resume", "queue/clear", "git/status", "git/diff", "git/commit", "git/push", "git/pull", "git/checkout", "git/createBranch", "git/createWorktree", "git/stage", "git/unstage", "git/discard", "git/createPr", "git/undoCommit", "git/branches", "git/switchBranch", "git/revert", "git/deleteBranch", "git/removeWorktree", "git/worktrees", "git/log", "git/commitShow", "workspace/readFile", "workspace/readImage", "workspace/list", "workspace/searchFiles", "workspace/resolveFileLink", "workspace/browseDirs", "workspace/checkpoint", "workspace/diffCheckpoint", "workspace/applyCheckpoint", "workspace/applyPatch", "workspace/exists", "project/list", "project/resolve", "project/add", "project/remove", "project/rename", "sync/changes", "settings/get", "settings/set", "device/describe", "device/rename", "agent/list", "agent/models", "agent/commands", "agent/usageStats", "agent/doctor", "metrics/get", "metrics/export", "metrics/import", "auth/status", "auth/login", "auth/logout", "notifications/register", "notifications/update", "notifications/unregister", "bridge/status", "bridge/generatePairingQr", "bridge/connectedPhones", "bridge/disconnectPhone", "bridge/trustedDevices", "bridge/removeTrustedDevice", "desktop/attach", "desktop/detach"];
|
|
6
|
+
export declare const METHOD_NAMES: readonly ["thread/list", "thread/read", "thread/start", "thread/resume", "thread/fork", "thread/setModel", "thread/rename", "thread/setAccessMode", "thread/archive", "thread/unarchive", "thread/delete", "turn/list", "turn/read", "turn/send", "turn/cancel", "queue/resume", "queue/clear", "git/status", "git/diff", "git/commit", "git/push", "git/pull", "git/checkout", "git/createBranch", "git/createWorktree", "git/stage", "git/unstage", "git/discard", "git/createPr", "git/undoCommit", "git/branches", "git/switchBranch", "git/revert", "git/deleteBranch", "git/removeWorktree", "git/worktrees", "git/log", "git/commitShow", "workspace/readFile", "workspace/readImage", "workspace/list", "workspace/searchFiles", "workspace/resolveFileLink", "workspace/browseDirs", "workspace/checkpoint", "workspace/diffCheckpoint", "workspace/applyCheckpoint", "workspace/applyPatch", "workspace/exists", "project/list", "project/resolve", "project/add", "project/remove", "project/rename", "sync/changes", "settings/get", "settings/set", "device/describe", "device/rename", "agent/list", "agent/models", "agent/commands", "agent/usageStats", "agent/doctor", "metrics/get", "metrics/export", "metrics/import", "auth/status", "auth/login", "auth/logout", "notifications/register", "notifications/update", "notifications/unregister", "bridge/status", "bridge/generatePairingQr", "bridge/connectedPhones", "bridge/disconnectPhone", "bridge/trustedDevices", "bridge/removeTrustedDevice", "bridge/update", "desktop/attach", "desktop/detach"];
|
|
7
7
|
export declare function isKnownMethod(method: string): method is JsonRpcMethodName;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"method-registry.js","sourceRoot":"","sources":["../../../src/jsonrpc/method-registry.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,kBAAkB;IAClB,aAAa;IACb,aAAa;IACb,cAAc;IACd,eAAe;IACf,aAAa;IACb,iBAAiB;IACjB,eAAe;IACf,sBAAsB;IACtB,gBAAgB;IAChB,kBAAkB;IAClB,eAAe;IACf,WAAW;IACX,WAAW;IACX,WAAW;IACX,aAAa;IACb,gBAAgB;IAChB,cAAc;IACd,aAAa;IACb,MAAM;IACN,YAAY;IACZ,UAAU;IACV,YAAY;IACZ,UAAU;IACV,UAAU;IACV,cAAc;IACd,kBAAkB;IAClB,oBAAoB;IACpB,WAAW;IACX,aAAa;IACb,aAAa;IACb,cAAc;IACd,gBAAgB;IAChB,cAAc;IACd,kBAAkB;IAClB,YAAY;IACZ,kBAAkB;IAClB,oBAAoB;IACpB,eAAe;IACf,SAAS;IACT,gBAAgB;IAChB,YAAY;IACZ,oBAAoB;IACpB,qBAAqB;IACrB,gBAAgB;IAChB,uBAAuB;IACvB,2BAA2B;IAC3B,sBAAsB;IACtB,sBAAsB;IACtB,0BAA0B;IAC1B,2BAA2B;IAC3B,sBAAsB;IACtB,kBAAkB;IAClB,WAAW;IACX,cAAc;IACd,iBAAiB;IACjB,aAAa;IACb,gBAAgB;IAChB,gBAAgB;IAChB,mCAAmC;IACnC,cAAc;IACd,cAAc;IACd,cAAc;IACd,iBAAiB;IACjB,eAAe;IACf,SAAS;IACT,YAAY;IACZ,cAAc;IACd,gBAAgB;IAChB,kBAAkB;IAClB,cAAc;IACd,yEAAyE;IACzE,aAAa;IACb,gBAAgB;IAChB,gBAAgB;IAChB,OAAO;IACP,aAAa;IACb,YAAY;IACZ,aAAa;IACb,uBAAuB;IACvB,wBAAwB;IACxB,sBAAsB;IACtB,0BAA0B;IAC1B,iBAAiB;IACjB,eAAe;IACf,0BAA0B;IAC1B,wBAAwB;IACxB,wBAAwB;IACxB,uBAAuB;IACvB,4BAA4B;IAC5B,mEAAmE;IACnE,gBAAgB;IAChB,gBAAgB;CACR,CAAC;AAQX,MAAM,sBAAsB,GAAqB,IAAI,CAAC;AACtD,MAAM,sBAAsB,GAAqB,IAAI,CAAC;AACtD,KAAK,sBAAsB,CAAC;AAC5B,KAAK,sBAAsB,CAAC;AAE5B,MAAM,eAAe,GAAwB,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;AAEnE,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,OAAO,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACrC,CAAC"}
|
|
1
|
+
{"version":3,"file":"method-registry.js","sourceRoot":"","sources":["../../../src/jsonrpc/method-registry.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,kBAAkB;IAClB,aAAa;IACb,aAAa;IACb,cAAc;IACd,eAAe;IACf,aAAa;IACb,iBAAiB;IACjB,eAAe;IACf,sBAAsB;IACtB,gBAAgB;IAChB,kBAAkB;IAClB,eAAe;IACf,WAAW;IACX,WAAW;IACX,WAAW;IACX,aAAa;IACb,gBAAgB;IAChB,cAAc;IACd,aAAa;IACb,MAAM;IACN,YAAY;IACZ,UAAU;IACV,YAAY;IACZ,UAAU;IACV,UAAU;IACV,cAAc;IACd,kBAAkB;IAClB,oBAAoB;IACpB,WAAW;IACX,aAAa;IACb,aAAa;IACb,cAAc;IACd,gBAAgB;IAChB,cAAc;IACd,kBAAkB;IAClB,YAAY;IACZ,kBAAkB;IAClB,oBAAoB;IACpB,eAAe;IACf,SAAS;IACT,gBAAgB;IAChB,YAAY;IACZ,oBAAoB;IACpB,qBAAqB;IACrB,gBAAgB;IAChB,uBAAuB;IACvB,2BAA2B;IAC3B,sBAAsB;IACtB,sBAAsB;IACtB,0BAA0B;IAC1B,2BAA2B;IAC3B,sBAAsB;IACtB,kBAAkB;IAClB,WAAW;IACX,cAAc;IACd,iBAAiB;IACjB,aAAa;IACb,gBAAgB;IAChB,gBAAgB;IAChB,mCAAmC;IACnC,cAAc;IACd,cAAc;IACd,cAAc;IACd,iBAAiB;IACjB,eAAe;IACf,SAAS;IACT,YAAY;IACZ,cAAc;IACd,gBAAgB;IAChB,kBAAkB;IAClB,cAAc;IACd,yEAAyE;IACzE,aAAa;IACb,gBAAgB;IAChB,gBAAgB;IAChB,OAAO;IACP,aAAa;IACb,YAAY;IACZ,aAAa;IACb,uBAAuB;IACvB,wBAAwB;IACxB,sBAAsB;IACtB,0BAA0B;IAC1B,iBAAiB;IACjB,eAAe;IACf,0BAA0B;IAC1B,wBAAwB;IACxB,wBAAwB;IACxB,uBAAuB;IACvB,4BAA4B;IAC5B,eAAe;IACf,mEAAmE;IACnE,gBAAgB;IAChB,gBAAgB;CACR,CAAC;AAQX,MAAM,sBAAsB,GAAqB,IAAI,CAAC;AACtD,MAAM,sBAAsB,GAAqB,IAAI,CAAC;AACtD,KAAK,sBAAsB,CAAC;AAC5B,KAAK,sBAAsB,CAAC;AAE5B,MAAM,eAAe,GAAwB,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;AAEnE,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,OAAO,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACrC,CAAC"}
|
|
@@ -12,7 +12,7 @@ import type { AuthStatus, Project, ProjectAddParams, ProjectRemoveParams, Projec
|
|
|
12
12
|
import type { BridgeSettings, SettingsSetParams, SyncChanges, SyncChangesParams } from '../models/sync.js';
|
|
13
13
|
import type { ApprovalResponse } from '../models/approval.js';
|
|
14
14
|
import type { QuestionResponse } from '../models/question.js';
|
|
15
|
-
import type { BridgeStatus, ConnectedPhone, DeviceDescribeParams, DeviceDescription, DeviceRenameParams, TrustedDevice } from '../models/session.js';
|
|
15
|
+
import type { BridgeStatus, BridgeUpdate, ConnectedPhone, DeviceDescribeParams, DeviceDescription, DeviceRenameParams, TrustedDevice } from '../models/session.js';
|
|
16
16
|
import type { PairingPayload } from '../e2ee/pairing-payload.js';
|
|
17
17
|
import type { AgentCommand, AgentCommandInvocation, AgentDescriptor, AgentDiagnosis, AgentId, AgentModel } from '../agents/agent-capabilities.js';
|
|
18
18
|
import type { UsageStatsParams, UsageStatsResult } from '../models/usage.js';
|
|
@@ -169,17 +169,6 @@ export interface TurnSendResult {
|
|
|
169
169
|
queued?: boolean;
|
|
170
170
|
/** 1-based place in the queue when `queued` is true (1 = runs next). */
|
|
171
171
|
queuePosition?: number;
|
|
172
|
-
/**
|
|
173
|
-
* True when the agent took the message **into the turn already running**
|
|
174
|
-
* rather than making it wait (status `delivered`, see `TurnStatus`). It will
|
|
175
|
-
* never run as a turn of its own — the reply belongs to the turn it joined —
|
|
176
|
-
* so the client renders the user's message in place and stops offering to
|
|
177
|
-
* edit or cancel it. Mutually exclusive with {@link queued}.
|
|
178
|
-
*
|
|
179
|
-
* Only ever true when the agent advertises `AgentCapabilities.steering`; on
|
|
180
|
-
* every other agent a follow-up still comes back `queued`.
|
|
181
|
-
*/
|
|
182
|
-
delivered?: boolean;
|
|
183
172
|
}
|
|
184
173
|
export interface QueueStateResult {
|
|
185
174
|
/** Queued turn ids in drain order. */
|
|
@@ -730,6 +719,10 @@ export interface JsonRpcMethodRegistry {
|
|
|
730
719
|
};
|
|
731
720
|
result: void;
|
|
732
721
|
};
|
|
722
|
+
'bridge/update': {
|
|
723
|
+
params: void;
|
|
724
|
+
result: BridgeUpdate;
|
|
725
|
+
};
|
|
733
726
|
'desktop/attach': {
|
|
734
727
|
params: DesktopAttachParams;
|
|
735
728
|
result: DesktopAttachResult;
|
|
@@ -13,7 +13,7 @@ import type { ApprovalDecision } from '../models/approval.js';
|
|
|
13
13
|
import type { QueuePausedReason, Thread, Turn } from '../models/thread.js';
|
|
14
14
|
import type { Project } from '../models/project.js';
|
|
15
15
|
import type { BridgeSettings, ClientPresence } from '../models/sync.js';
|
|
16
|
-
import type { TrustedDevice } from '../models/session.js';
|
|
16
|
+
import type { BridgeUpdate, TrustedDevice } from '../models/session.js';
|
|
17
17
|
import type { AgentDescriptor } from '../agents/agent-capabilities.js';
|
|
18
18
|
export declare const StreamNotification: {
|
|
19
19
|
readonly TurnStarted: "stream/turn/started";
|
|
@@ -27,11 +27,6 @@ export declare const StreamNotification: {
|
|
|
27
27
|
readonly TurnAborted: "stream/turn/aborted";
|
|
28
28
|
/** A queued turn was removed before it ever ran (status → `cancelled`). */
|
|
29
29
|
readonly TurnCancelled: "stream/turn/cancelled";
|
|
30
|
-
/**
|
|
31
|
-
* A queued turn was handed to the agent **inside the turn already running**
|
|
32
|
-
* instead of waiting for it (status → `delivered`).
|
|
33
|
-
*/
|
|
34
|
-
readonly TurnDelivered: "stream/turn/delivered";
|
|
35
30
|
/** The thread's message queue changed (queued, drained, cancelled, paused). */
|
|
36
31
|
readonly QueueUpdated: "stream/queue/updated";
|
|
37
32
|
/** The agent resolved an alias (e.g. `opus`) to a concrete model id for this turn. */
|
|
@@ -66,6 +61,12 @@ export declare const StreamNotification: {
|
|
|
66
61
|
readonly DevicesUpdated: "stream/devices/updated";
|
|
67
62
|
/** An agent became available or unavailable (installed, removed). */
|
|
68
63
|
readonly AgentsUpdated: "stream/agents/updated";
|
|
64
|
+
/**
|
|
65
|
+
* The bridge's own update changed: a newer version was published, or an
|
|
66
|
+
* update started or failed. The whole state, as `bridge/status` → `update`
|
|
67
|
+
* would answer now (idempotent).
|
|
68
|
+
*/
|
|
69
|
+
readonly BridgeUpdated: "stream/bridge/updated";
|
|
69
70
|
};
|
|
70
71
|
export type StreamNotification = (typeof StreamNotification)[keyof typeof StreamNotification];
|
|
71
72
|
export interface TurnStartedParams {
|
|
@@ -149,22 +150,6 @@ export interface TurnCancelledParams {
|
|
|
149
150
|
threadId: string;
|
|
150
151
|
turnId: string;
|
|
151
152
|
}
|
|
152
|
-
/**
|
|
153
|
-
* A queued turn reached the agent **without waiting**: it was folded into the
|
|
154
|
-
* turn that was already running (its status is now `delivered`), the way a CLI
|
|
155
|
-
* picks up what you typed while it worked. It will never run as a turn of its
|
|
156
|
-
* own — the answer is part of `intoTurnId`.
|
|
157
|
-
*
|
|
158
|
-
* The client keeps the user's message where it is and stops offering to edit or
|
|
159
|
-
* cancel it: the agent already has it.
|
|
160
|
-
*/
|
|
161
|
-
export interface TurnDeliveredParams {
|
|
162
|
-
threadId: string;
|
|
163
|
-
/** The queued turn that was handed over. */
|
|
164
|
-
turnId: string;
|
|
165
|
-
/** The running turn it was folded into; its reply covers both messages. */
|
|
166
|
-
intoTurnId: string;
|
|
167
|
-
}
|
|
168
153
|
/**
|
|
169
154
|
* The thread's message queue changed. Carries the WHOLE state rather than a
|
|
170
155
|
* delta, so it is idempotent: a client that missed one (backgrounded, mid-
|
|
@@ -240,6 +225,10 @@ export interface DevicesUpdatedParams {
|
|
|
240
225
|
export interface AgentsUpdatedParams {
|
|
241
226
|
agents: AgentDescriptor[];
|
|
242
227
|
}
|
|
228
|
+
/** The bridge's update, as `bridge/status` → `update` would answer now. */
|
|
229
|
+
export interface BridgeUpdatedParams {
|
|
230
|
+
update: BridgeUpdate;
|
|
231
|
+
}
|
|
243
232
|
/**
|
|
244
233
|
* A user turn was stored: it started right away (`status` `pending`) or it was
|
|
245
234
|
* queued behind the running one (`queued`). `turn.messages` holds the user's
|
|
@@ -10,11 +10,6 @@ export const StreamNotification = {
|
|
|
10
10
|
TurnAborted: 'stream/turn/aborted',
|
|
11
11
|
/** A queued turn was removed before it ever ran (status → `cancelled`). */
|
|
12
12
|
TurnCancelled: 'stream/turn/cancelled',
|
|
13
|
-
/**
|
|
14
|
-
* A queued turn was handed to the agent **inside the turn already running**
|
|
15
|
-
* instead of waiting for it (status → `delivered`).
|
|
16
|
-
*/
|
|
17
|
-
TurnDelivered: 'stream/turn/delivered',
|
|
18
13
|
/** The thread's message queue changed (queued, drained, cancelled, paused). */
|
|
19
14
|
QueueUpdated: 'stream/queue/updated',
|
|
20
15
|
/** The agent resolved an alias (e.g. `opus`) to a concrete model id for this turn. */
|
|
@@ -49,5 +44,11 @@ export const StreamNotification = {
|
|
|
49
44
|
DevicesUpdated: 'stream/devices/updated',
|
|
50
45
|
/** An agent became available or unavailable (installed, removed). */
|
|
51
46
|
AgentsUpdated: 'stream/agents/updated',
|
|
47
|
+
/**
|
|
48
|
+
* The bridge's own update changed: a newer version was published, or an
|
|
49
|
+
* update started or failed. The whole state, as `bridge/status` → `update`
|
|
50
|
+
* would answer now (idempotent).
|
|
51
|
+
*/
|
|
52
|
+
BridgeUpdated: 'stream/bridge/updated',
|
|
52
53
|
};
|
|
53
54
|
//# sourceMappingURL=notifications.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifications.js","sourceRoot":"","sources":["../../../src/jsonrpc/notifications.ts"],"names":[],"mappings":"AAkBA,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,WAAW,EAAE,qBAAqB;IAClC,YAAY,EAAE,sBAAsB;IACpC,kFAAkF;IAClF,aAAa,EAAE,uBAAuB;IACtC,mFAAmF;IACnF,YAAY,EAAE,sBAAsB;IACpC,aAAa,EAAE,uBAAuB;IACtC,SAAS,EAAE,mBAAmB;IAC9B,WAAW,EAAE,qBAAqB;IAClC,2EAA2E;IAC3E,aAAa,EAAE,uBAAuB;IACtC
|
|
1
|
+
{"version":3,"file":"notifications.js","sourceRoot":"","sources":["../../../src/jsonrpc/notifications.ts"],"names":[],"mappings":"AAkBA,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,WAAW,EAAE,qBAAqB;IAClC,YAAY,EAAE,sBAAsB;IACpC,kFAAkF;IAClF,aAAa,EAAE,uBAAuB;IACtC,mFAAmF;IACnF,YAAY,EAAE,sBAAsB;IACpC,aAAa,EAAE,uBAAuB;IACtC,SAAS,EAAE,mBAAmB;IAC9B,WAAW,EAAE,qBAAqB;IAClC,2EAA2E;IAC3E,aAAa,EAAE,uBAAuB;IACtC,+EAA+E;IAC/E,YAAY,EAAE,sBAAsB;IACpC,sFAAsF;IACtF,aAAa,EAAE,uBAAuB;IACtC;;;;OAIG;IACH,aAAa,EAAE,uBAAuB;IACtC,4BAA4B;IAC5B,aAAa,EAAE,uBAAuB;IACtC;;;;OAIG;IACH,WAAW,EAAE,qBAAqB;IAClC,oEAAoE;IACpE,gBAAgB,EAAE,0BAA0B;IAC5C,6EAA6E;IAC7E,gBAAgB,EAAE,0BAA0B;IAC5C,qDAAqD;IACrD,cAAc,EAAE,wBAAwB;IACxC,wEAAwE;IACxE,cAAc,EAAE,wBAAwB;IACxC,yEAAyE;IACzE,eAAe,EAAE,yBAAyB;IAC1C,0CAA0C;IAC1C,eAAe,EAAE,yBAAyB;IAC1C,uDAAuD;IACvD,cAAc,EAAE,wBAAwB;IACxC,qEAAqE;IACrE,aAAa,EAAE,uBAAuB;IACtC;;;;OAIG;IACH,aAAa,EAAE,uBAAuB;CAC9B,CAAC"}
|
|
@@ -86,7 +86,8 @@ export interface LocalControlMessageFrame {
|
|
|
86
86
|
export type LocalControlFrame = LocalControlHelloFrame | LocalControlMessageFrame;
|
|
87
87
|
/** Query parameters of the upgrade URL: `/control?client=<id>&resume=<seq>&instance=<id>`. */
|
|
88
88
|
export interface LocalControlConnectParams {
|
|
89
|
-
/** Stable name of the client (e.g. `desktop`); one live
|
|
89
|
+
/** Stable name of the client (e.g. `desktop-3f9a1c2b7d4e`, `cli`); one live
|
|
90
|
+
* connection per name. */
|
|
90
91
|
client: string;
|
|
91
92
|
/** Last notification `seq` the client applied (0 or absent on a fresh start). */
|
|
92
93
|
resume?: number;
|
|
@@ -95,6 +96,17 @@ export interface LocalControlConnectParams {
|
|
|
95
96
|
}
|
|
96
97
|
/** Whether `id` is an acceptable local client name (lowercase, short, no separators). */
|
|
97
98
|
export declare function isValidLocalClientId(id: string): boolean;
|
|
99
|
+
/**
|
|
100
|
+
* The name Uxnan Desktop's client ids start with. Each desktop **profile** — the
|
|
101
|
+
* installed app, a development build, a disposable `UXNAN_DATA_DIR` — connects
|
|
102
|
+
* under its own `desktop-<profile>` id, because the channel keeps one live
|
|
103
|
+
* connection per name: two desktops sharing one would supersede each other in
|
|
104
|
+
* an endless reconnect loop and trade the same outbound log, presence and
|
|
105
|
+
* tools back and forth (architecture/02a §5.8.15).
|
|
106
|
+
*/
|
|
107
|
+
export declare const DESKTOP_LOCAL_CLIENT = "desktop";
|
|
108
|
+
/** Whether a local client id is Uxnan Desktop's (`desktop` or `desktop-<profile>`). */
|
|
109
|
+
export declare function isDesktopClientId(id: string): boolean;
|
|
98
110
|
/**
|
|
99
111
|
* The receiver id a local client is registered under in the bridge's session
|
|
100
112
|
* registry. Prefixed so it can never collide with a paired phone's device id.
|
|
@@ -36,6 +36,20 @@ const CLIENT_ID_PATTERN = /^[a-z0-9][a-z0-9-]{0,31}$/;
|
|
|
36
36
|
export function isValidLocalClientId(id) {
|
|
37
37
|
return CLIENT_ID_PATTERN.test(id);
|
|
38
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* The name Uxnan Desktop's client ids start with. Each desktop **profile** — the
|
|
41
|
+
* installed app, a development build, a disposable `UXNAN_DATA_DIR` — connects
|
|
42
|
+
* under its own `desktop-<profile>` id, because the channel keeps one live
|
|
43
|
+
* connection per name: two desktops sharing one would supersede each other in
|
|
44
|
+
* an endless reconnect loop and trade the same outbound log, presence and
|
|
45
|
+
* tools back and forth (architecture/02a §5.8.15).
|
|
46
|
+
*/
|
|
47
|
+
export const DESKTOP_LOCAL_CLIENT = 'desktop';
|
|
48
|
+
/** Whether a local client id is Uxnan Desktop's (`desktop` or `desktop-<profile>`). */
|
|
49
|
+
export function isDesktopClientId(id) {
|
|
50
|
+
return (isValidLocalClientId(id) &&
|
|
51
|
+
(id === DESKTOP_LOCAL_CLIENT || id.startsWith(`${DESKTOP_LOCAL_CLIENT}-`)));
|
|
52
|
+
}
|
|
39
53
|
/**
|
|
40
54
|
* The receiver id a local client is registered under in the bridge's session
|
|
41
55
|
* registry. Prefixed so it can never collide with a paired phone's device id.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-control.js","sourceRoot":"","sources":["../../../src/local-control/local-control.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,2DAA2D;AAC3D,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAExC;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,oBAAoB,CAAC;AAEvD,0CAA0C;AAC1C,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAAC;AAE7C;;;GAGG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"local-control.js","sourceRoot":"","sources":["../../../src/local-control/local-control.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,2DAA2D;AAC3D,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAExC;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,oBAAoB,CAAC;AAEvD,0CAA0C;AAC1C,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAAC;AAE7C;;;GAGG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAsE9D,MAAM,iBAAiB,GAAG,2BAA2B,CAAC;AAEtD,yFAAyF;AACzF,MAAM,UAAU,oBAAoB,CAAC,EAAU;IAC7C,OAAO,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,SAAS,CAAC;AAE9C,uFAAuF;AACvF,MAAM,UAAU,iBAAiB,CAAC,EAAU;IAC1C,OAAO,CACL,oBAAoB,CAAC,EAAE,CAAC;QACxB,CAAC,EAAE,KAAK,oBAAoB,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,oBAAoB,GAAG,CAAC,CAAC,CAC3E,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,OAAO,SAAS,QAAQ,EAAE,CAAC;AAC7B,CAAC;AAuBD;;sCAEsC;AACtC,MAAM,CAAC,MAAM,kBAAkB,GAAG,aAAa,CAAC;AAEhD;;kBAEkB;AAClB,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,OAAO,kBAAkB,CAAC,GAAG,CAAC,CAAC;AACjC,CAAC;AAED;;yBAEyB;AACzB,MAAM,CAAC,MAAM,uBAAuB,GAAG,eAAe,CAAC;AAEvD,iFAAiF;AACjF,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,OAAO,0DAA0D,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC9E,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,OAAO,yBAAyB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -75,17 +75,17 @@ export interface BridgeStatus {
|
|
|
75
75
|
platform: NodeJS.Platform | string;
|
|
76
76
|
uptimeMs: number;
|
|
77
77
|
/**
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
*
|
|
85
|
-
* (
|
|
86
|
-
*
|
|
78
|
+
* The bridge's own update: the newest published version it knows of, whether
|
|
79
|
+
* it can install that version and restart itself, and how an update under way
|
|
80
|
+
* is going ({@link BridgeUpdate}). Every client reads it here and follows
|
|
81
|
+
* `stream/bridge/updated`; none of them asks npm itself.
|
|
82
|
+
*
|
|
83
|
+
* **Absent means the bridge predates updating itself**, and is therefore older
|
|
84
|
+
* than the client reading this: a client offers the update it can do on its
|
|
85
|
+
* own (Uxnan Desktop installs the published bridge) or says to update the
|
|
86
|
+
* bridge on the PC (the phone).
|
|
87
87
|
*/
|
|
88
|
-
|
|
88
|
+
update?: BridgeUpdate;
|
|
89
89
|
/**
|
|
90
90
|
* Threads with a turn in flight right now, whichever client started it.
|
|
91
91
|
* Absent on an older bridge. A client uses it to wait for a quiet moment
|
|
@@ -110,6 +110,58 @@ export interface BridgeStatus {
|
|
|
110
110
|
/** Who is connected right now. Absent on an older bridge. */
|
|
111
111
|
clients?: ClientPresence[];
|
|
112
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* Where an update of the bridge stands. `updating` spans the whole handover —
|
|
115
|
+
* the bridge stops, installs the published version and its service starts the
|
|
116
|
+
* new one — so a client sees the connection drop and come back on the new
|
|
117
|
+
* {@link BridgeUpdate.version}; the outcome of a failed install is reported by
|
|
118
|
+
* the bridge that comes back.
|
|
119
|
+
*/
|
|
120
|
+
export type BridgeUpdatePhase = 'idle' | 'updating' | 'failed';
|
|
121
|
+
/**
|
|
122
|
+
* Why an update did not happen:
|
|
123
|
+
* - `busy`: a turn is running on some client — the bridge never restarts
|
|
124
|
+
* under one; try again when it ends.
|
|
125
|
+
* - `unsupported`: this bridge cannot replace itself (see
|
|
126
|
+
* {@link BridgeUpdate.canApply}).
|
|
127
|
+
* - `permission`: npm could not write its global folder; {@link
|
|
128
|
+
* BridgeUpdateFailure.command} is the command to run by hand.
|
|
129
|
+
* - `install`: npm failed for another reason (offline, registry, disk).
|
|
130
|
+
*/
|
|
131
|
+
export type BridgeUpdateFailureReason = 'busy' | 'unsupported' | 'permission' | 'install';
|
|
132
|
+
export interface BridgeUpdateFailure {
|
|
133
|
+
reason: BridgeUpdateFailureReason;
|
|
134
|
+
/** What went wrong, for a person (npm's last lines for `install`). */
|
|
135
|
+
message: string;
|
|
136
|
+
/** The command that does the update by hand, when that is the way out. */
|
|
137
|
+
command?: string;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* The bridge's own update, owned by the bridge: it checks the npm registry
|
|
141
|
+
* itself (hourly while it runs), installs the published version and restarts on
|
|
142
|
+
* it (`bridge/update`), and tells every client with `stream/bridge/updated`.
|
|
143
|
+
*/
|
|
144
|
+
export interface BridgeUpdate {
|
|
145
|
+
/** The version running now. */
|
|
146
|
+
version: string;
|
|
147
|
+
/** The newest version published under npm's `latest` dist-tag, once known. */
|
|
148
|
+
latestVersion?: string;
|
|
149
|
+
/** {@link latestVersion} is strictly newer than {@link version}. */
|
|
150
|
+
available: boolean;
|
|
151
|
+
/**
|
|
152
|
+
* This bridge can install the published version and restart on it by
|
|
153
|
+
* itself: it runs as the user's service from a global npm install, with npm
|
|
154
|
+
* beside it. False for a bridge started in a terminal or run from a source
|
|
155
|
+
* checkout — {@link unsupportedReason} says which.
|
|
156
|
+
*/
|
|
157
|
+
canApply: boolean;
|
|
158
|
+
unsupportedReason?: string;
|
|
159
|
+
phase: BridgeUpdatePhase;
|
|
160
|
+
/** The version being installed while {@link phase} is `updating`. */
|
|
161
|
+
targetVersion?: string;
|
|
162
|
+
/** Why the last attempt failed, while {@link phase} is `failed`. */
|
|
163
|
+
failure?: BridgeUpdateFailure;
|
|
164
|
+
}
|
|
113
165
|
/**
|
|
114
166
|
* What started the bridge: its own user service (`service` — the normal case,
|
|
115
167
|
* it outlives Uxnan Desktop), Uxnan Desktop directly (`desktop`), or a person
|
|
@@ -133,8 +185,10 @@ export interface BridgeFeatures {
|
|
|
133
185
|
messageQueue?: boolean;
|
|
134
186
|
/**
|
|
135
187
|
* The bridge can hand a queued turn to the agent **inside the turn already
|
|
136
|
-
* running**, for agents whose CLI has an input channel mid-turn —
|
|
137
|
-
*
|
|
188
|
+
* running**, for agents whose CLI has an input channel mid-turn — the running
|
|
189
|
+
* turn completes and the handed-over one starts at once, carrying the rest of
|
|
190
|
+
* the agent's run (`stream/turn/completed` then `stream/turn/started`, as a
|
|
191
|
+
* queue that drained early). Absent/false → the
|
|
138
192
|
* client must expect every follow-up to wait for the current turn to end, and
|
|
139
193
|
* must not promise otherwise in its UI.
|
|
140
194
|
*
|
|
@@ -17,14 +17,13 @@ export type MessageRole = 'user' | 'assistant' | 'system' | 'tool';
|
|
|
17
17
|
* thread (never deleted) so the user's message stays visible with a "cancelled"
|
|
18
18
|
* mark instead of silently vanishing; distinct from `aborted` precisely so a
|
|
19
19
|
* client can tell "never ran" from "interrupted".
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* with no assistant reply hanging off it.
|
|
20
|
+
*
|
|
21
|
+
* A queued turn the agent takes **into the turn already running** (see
|
|
22
|
+
* `AgentCapabilities.steering`) goes straight to `streaming`: the running turn
|
|
23
|
+
* completes there and this one carries the rest of the agent's run, so what the
|
|
24
|
+
* agent says after taking the message is shown under it.
|
|
26
25
|
*/
|
|
27
|
-
export type TurnStatus = 'queued' | 'pending' | 'streaming' | 'completed' | 'error' | 'aborted' | 'cancelled'
|
|
26
|
+
export type TurnStatus = 'queued' | 'pending' | 'streaming' | 'completed' | 'error' | 'aborted' | 'cancelled';
|
|
28
27
|
export type ThreadStatus = 'active' | 'idle' | 'archived';
|
|
29
28
|
/**
|
|
30
29
|
* Why a thread's message queue is held instead of draining:
|
|
@@ -81,12 +80,6 @@ export interface Turn {
|
|
|
81
80
|
messages: Message[];
|
|
82
81
|
createdAt: number;
|
|
83
82
|
completedAt?: number;
|
|
84
|
-
/**
|
|
85
|
-
* For a `delivered` turn: the id of the turn its message was folded into.
|
|
86
|
-
* The reply lives there, so a client renders this turn's user message in
|
|
87
|
-
* place and expects no assistant message of its own. Absent otherwise.
|
|
88
|
-
*/
|
|
89
|
-
deliveredIntoTurnId?: string;
|
|
90
83
|
}
|
|
91
84
|
/**
|
|
92
85
|
* Per-thread access (approval) mode: how much the agent may do before it must
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uxnan/shared",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.19-alpha.20260926",
|
|
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",
|